postgresql.UUID server default always compares to false, thereby always autogenerating

Issue #365 resolved
Peter Lada
created an issue


My sqlalchemy model:

class Issue(Base):
    __tablename__ = 'issue'
    id = Column(Integer, primary_key=True) 
    uuid = Column(postgresql.UUID, nullable=False, index=True, default=uuid.uuid4(), server_default=text("uuid_generate_v4()"))

Configured with compare_server_default=True

Yields a autogenerated revision each time, setting the server_default=sa.Text('uuid_generate_v4()')


Comparing the server defaults with:

SELECT uuid_generate_v4() = uuid_generate_v4() yields False (with an exceptionally high probability).


def my_compare_server_default(context, inspected_column, metadata_column,
                              inspected_default, metadata_default, rendered_metadata_default):
    if type(inspected_column.type).__name__ == 'UUID':
        if inspected_default == rendered_metadata_default:
            print("they are the same")
            return False  # unintuitive: no need for migration
            return True  # unintuitive: needs a migration
    return None

and in compare_server_default=my_compare_server_default

Comments (1)

  1. Michael Bayer repo owner
    • Added a fix to Postgresql server default comparison which first checks if the text of the default is identical to the original, before attempting to actually run the default. This accomodates for default-generation functions that generate a new value each time such as a uuid function. fixes #365
    • test against uuid_generate_v4() directly, but this requires extensions to be installed. should come up with a built in function for this test

    → <<cset 9538c3e1a71c>>

  2. Log in to comment