API Reference¶
Entry points¶
comdab - Compare Database Schemas
Loïc Simon 2025, MIT License
- comdab.generate_migrations(source_connection: Connection, target_connection: Connection, generator: MigrationGeneratorPort, *, source_schema: str = 'public', target_schema: str = 'public', rules: dict[ComdabPath, ComdabStrategy] | None = None, allow_unknown_types: bool = False) None[source]¶
Generate migrations from a source schema to a target schema.
This is the highest-level, all-in-one comdab function.
- Parameters:
source_connection – A SQLAlchemy
connectionestablished to the database we want to migrate.target_connection – A SQLAlchemy
connectionestablished to a database with the desired state to reach.generator – The
MigrationGeneratorPortto use to generate migrations after the differences are found.source_schema – The name of the database schema to compare for the
source_connection.target_schema – The name of the database schema to compare for the
target_connection.rules – An optional set of rules to allow some differences between the schemas, or report them as warnings. See Ignore rules for more details.
allow_unknown_types – If
True, SQL data types not handed (yet) by comdab will be modeled as “unknown” and compared based on their name only. IfFalse(the default), encountering an unknown name will raise anUnhandledTypeError.
- comdab.compare_databases(left_connection: Connection, right_connection: Connection, *, left_schema: str = 'public', right_schema: str = 'public', rules: dict[ComdabPath, ComdabStrategy] | None = None, allow_unknown_types: bool = False) list[ComdabReport][source]¶
Build and compare two database schemas, from their SQLAlchemy connection.
- Parameters:
left_connection – A SQLAlchemy
connectionestablished to the first database to compare.right_connection – A SQLAlchemy
connectionestablished to the second database to compare.left_schema – The name of the database schema to compare for the
left_connection.right_schema – The name of the database schema to compare for the
right_connection.rules – An optional set of rules to allow some differences between the schemas, or report them as warnings. See Ignore rules for more details.
allow_unknown_types – If
True, SQL data types not handed (yet) by comdab will be modeled as “unknown” and compared based on their name only. IfFalse(the default), encountering an unknown name will raise anUnhandledTypeError.
- comdab.build_comdab_schema(connection: Connection, *, schema: str = 'public', allow_unknown_types: bool = False) ComdabSchema[source]¶
Build a database-agnostic, SQLAlchemy-independent representation of a database schema.
This is the internal representation used for comparison by comdab.
- Parameters:
connection – A SQLAlchemy
connectionestablished to the database to reflect.schema – The name of the database schema to reflect.
allow_unknown_types – If
True, SQL data types not handed (yet) by comdab will be modeled as “unknown” and compared based on their name only. IfFalse(the default), encountering an unknown name will raise anUnhandledTypeError.
- comdab.compare_comdab_schemas(left: ComdabSchema, right: ComdabSchema, *, rules: dict[ComdabPath, ComdabStrategy] | None = None) list[ComdabReport][source]¶
Compare two already built database schemas.
This is a pure function, needing no connection to a database.
- Parameters:
left – The first schema to compare, as produced by
build_comdab_schema().right – The second schema to compare, as produced by
build_comdab_schema().rules – An optional set of rules to allow some differences between the schemas, or report them as warnings. See Ignore rules for more details.
- comdab.generate_migrations_from_reports(target_schema: ComdabSchema, reports: Iterable[ComdabReport], generator: MigrationGeneratorPort) None[source]¶
Generate migrations from already build comdab reports.
This is a pure function, needing no connection to a database.
- Parameters:
target_schema – The comdab-built schema to reach after migrations.
reports – The comdab-built reports of differences between the source and target schemas.
generator – The
MigrationGeneratorPortto use to generate migrations from reports.
- comdab.ROOT = ROOT¶
The top-level comdab path, pointing to a whole
ComdabSchema.It’s attributes are, recursively, the corresponding schema attributes:
ROOT.tables['foo'].columnsrefer to all columns of the table namedfoo, eg. the dictionarysome_schema.tables['foo'].columns.Dictionary keys can be
regular expressions(or..., equivalent to'.*'), so thatROOT.tables['_.*'].columnsrefer to all columns of all tables beginning with an underscore.
- class comdab.MigrationGeneratorPort[source]¶
Abstract base class to generate migrations based on comdab reports.
Inherit this class and implement every method with your migration generation backend, then pass it to
generate_migrations().- abstractmethod create_table(*, table: ComdabTable) None[source]¶
Create a new table.
- abstractmethod drop_table(*, table: ComdabTable) None[source]¶
Drop a table.
- abstractmethod create_view(*, view: ComdabView) None[source]¶
Create a new view.
- abstractmethod drop_view(*, view: ComdabView) None[source]¶
Drop a view.
- abstractmethod create_sequence(*, sequence: ComdabSequence) None[source]¶
Create a new sequence.
- abstractmethod drop_sequence(*, sequence: ComdabSequence) None[source]¶
Drop a sequence.
- abstractmethod create_function(*, function: ComdabFunction) None[source]¶
Create a new function.
- abstractmethod drop_function(*, function: ComdabFunction) None[source]¶
Drop a function.
- abstractmethod create_custom_type(*, custom_type: ComdabCustomType) None[source]¶
Create a new custom type.
- abstractmethod drop_custom_type(*, custom_type: ComdabCustomType) None[source]¶
Drop a custom type.
- abstractmethod alter_schema_extra(*, old_extra: dict[str, Any], new_extra: dict[str, Any]) None[source]¶
Change some dialect-specific schema options.
- abstractmethod create_column(*, table: ComdabTable, column: ComdabColumn) None[source]¶
Create a new column.
- abstractmethod drop_column(*, table: ComdabTable, column: ComdabColumn) None[source]¶
Drop a column.
- abstractmethod create_constraint(*, table: ComdabTable, constraint: ComdabConstraint) None[source]¶
Create a new constraint.
- abstractmethod drop_constraint(*, table: ComdabTable, constraint: ComdabConstraint) None[source]¶
Drop a constraint.
- abstractmethod create_index(*, table: ComdabTable, index: ComdabIndex) None[source]¶
Create a new index.
- abstractmethod drop_index(*, table: ComdabTable, index: ComdabIndex) None[source]¶
Drop a index.
- abstractmethod create_trigger(*, table: ComdabTable, trigger: ComdabTrigger) None[source]¶
Create a new trigger.
- abstractmethod drop_trigger(*, table: ComdabTable, trigger: ComdabTrigger) None[source]¶
Drop a trigger.
- abstractmethod alter_table_extra(*, table: ComdabTable, old_extra: dict[str, Any], new_extra: dict[str, Any]) None[source]¶
Change some dialect-specific table options.
- abstractmethod alter_view_definition(*, view: ComdabView, old_definition: str, new_definition: str) None[source]¶
Change a view definition.
- abstractmethod alter_view_materialized(*, view: ComdabView, old_materialized: bool, new_materialized: bool) None[source]¶
Change whether a view is materialized.
- abstractmethod alter_view_extra(*, view: ComdabView, old_extra: dict[str, Any], new_extra: dict[str, Any]) None[source]¶
Change some dialect-specific view options.
- abstractmethod alter_sequence_type_name(*, sequence: ComdabSequence, old_type_name: str, new_type_name: str) None[source]¶
Change a sequence type.
- abstractmethod alter_sequence_start(*, sequence: ComdabSequence, old_start: int, new_start: int) None[source]¶
Change a sequence start point.
- abstractmethod alter_sequence_increment(*, sequence: ComdabSequence, old_increment: int, new_increment: int) None[source]¶
Change a sequence increment.
- abstractmethod alter_sequence_min(*, sequence: ComdabSequence, old_min: int, new_min: int) None[source]¶
Change a sequence minimal value.
- abstractmethod alter_sequence_max(*, sequence: ComdabSequence, old_max: int, new_max: int) None[source]¶
Change a sequence maximal value.
- abstractmethod alter_sequence_cycle(*, sequence: ComdabSequence, old_cycle: bool, new_cycle: bool) None[source]¶
Change whether a sequence cycles.
- abstractmethod alter_sequence_extra(*, sequence: ComdabSequence, old_extra: dict[str, Any], new_extra: dict[str, Any]) None[source]¶
Change some dialect-specific sequence options.
- abstractmethod alter_function_definition(*, function: ComdabFunction, old_definition: str, new_definition: str) None[source]¶
Change a function definition.
- abstractmethod alter_function_extra(*, function: ComdabFunction, old_extra: dict[str, Any], new_extra: dict[str, Any]) None[source]¶
Change some dialect-specific function options.
- abstractmethod alter_custom_type_values(*, custom_type: ComdabCustomType, old_values: list[str], new_values: list[str]) None[source]¶
Change the values of a custom type.
- abstractmethod alter_custom_type_extra(*, custom_type: ComdabCustomType, old_extra: dict[str, Any], new_extra: dict[str, Any]) None[source]¶
Change some dialect-specific custom type options.
- abstractmethod alter_column_type(*, table: ComdabTable, column: ComdabColumn, old_type: ComdabType, new_type: ComdabType) None[source]¶
Change a column type.
- abstractmethod alter_column_nullable(*, table: ComdabTable, column: ComdabColumn, old_nullable: bool, new_nullable: bool) None[source]¶
Change the nullability of a column.
- abstractmethod alter_column_default(*, table: ComdabTable, column: ComdabColumn, old_type: str | None, new_type: str | None) None[source]¶
Change the default value of a column.
- abstractmethod alter_column_generation_expression(*, table: ComdabTable, column: ComdabColumn, old_expr: str | None, new_expr: str | None) None[source]¶
Change the generation expression of a column.
- abstractmethod alter_column_extra(*, table: ComdabTable, column: ComdabColumn, old_extra: dict[str, Any], new_extra: dict[str, Any]) None[source]¶
Change some dialect-specific column options.
- abstractmethod alter_constraint_type(*, table: ComdabTable, constraint: ComdabConstraint, old_type: ComdabConstraintType, new_type: ComdabConstraintType) None[source]¶
Change a constraint type.
- abstractmethod alter_constraint_deferrable(*, table: ComdabTable, constraint: ComdabConstraint, old_deferrable: bool | None, new_deferrable: bool | None) None[source]¶
Change whether a constraint can be deferred.
- abstractmethod alter_constraint_initially(*, table: ComdabTable, constraint: ComdabConstraint, old_initially: str | None, new_initially: str | None) None[source]¶
Change a constraint initial state.
- abstractmethod alter_constraint_extra(*, table: ComdabTable, constraint: ComdabConstraint, old_extra: dict[str, Any], new_extra: dict[str, Any]) None[source]¶
Change some dialect-specific constraint options.
- abstractmethod alter_constraint_columns(*, table: ComdabTable, constraint: ComdabPrimaryKeyConstraint | ComdabUniqueConstraint, old_columns: set[str], new_columns: set[str]) None[source]¶
Change a PK / unique constraint columns.
- abstractmethod alter_constraint_columns_mapping(*, table: ComdabTable, constraint: ComdabForeignKeyConstraint, old_columns_mapping: dict[str, str], new_columns_mapping: dict[str, str]) None[source]¶
Change the columns mapping of a foreign key constraint.
- abstractmethod alter_constraint_on_update(*, table: ComdabTable, constraint: ComdabForeignKeyConstraint, old_on_update: str | None, new_on_update: str | None) None[source]¶
Change the ON UPDATE clause of a foreign key constraint.
- abstractmethod alter_constraint_on_delete(*, table: ComdabTable, constraint: ComdabForeignKeyConstraint, old_on_delete: str | None, new_on_delete: str | None) None[source]¶
Change the ON DELETE clause of a foreign key constraint.
- abstractmethod alter_constraint_sql_text(*, table: ComdabTable, constraint: ComdabCheckConstraint, old_sql_text: str, new_sql_text: str) None[source]¶
Change the clause of a check constraint.
- abstractmethod alter_constraint_attributes_and_operators(*, table: ComdabTable, constraint: ComdabExcludeConstraint, old_attributes_and_operators: list[tuple[str, str]], new_attributes_and_operators: list[tuple[str, str]]) None[source]¶
Change the attributes and operators of a exclusion constraint.
- abstractmethod alter_index_expressions(*, table: ComdabTable, index: ComdabIndex, old_expressions: list[str], new_expressions: list[str]) None[source]¶
Change the expressions of an index.
- abstractmethod alter_index_unique(*, table: ComdabTable, index: ComdabIndex, old_unique: bool, new_unique: bool) None[source]¶
Change if an index is unique.
- abstractmethod alter_index_extra(*, table: ComdabTable, index: ComdabIndex, old_extra: dict[str, Any], new_extra: dict[str, Any]) None[source]¶
Change some dialect-specific index options.
- abstractmethod alter_trigger_definition(*, table: ComdabTable, trigger: ComdabTrigger, old_definition: str, new_definition: str) None[source]¶
Change a trigger definition.
- class comdab.PartialMigrationGeneratorPort¶
Like
MigrationGeneratorPort, but does not require all migration methods to be implemented.By default,
NotImplementedErrorwill be raised if a missing method is called; to silently do nothing instead, useclass MyGenerator(PartialMigrationGeneratorPort, strict=False).
Reports¶
- class comdab.report.ComdabReport[source]¶
A difference between two database schemas, reported by comdab.
Should not be instantiated manually.
Examples
A column is nullable in the left schema, not in the right:
ComdabReport(level="error", path=ROOT.tables['foo'].columns['bar'].nullable, left=True, right=False)A table is present only in the left schema:
ComdabReport(level="error", path=ROOT.tables.left_only, left={'foo': ComdabTable(...)}, right={})Two columns are present only in the right schema:
ComdabReport(level="error", path=ROOT.tables['foo'].right_only, left={}, right={'bar': ComdabColumn(...)}) ComdabReport(level="error", path=ROOT.tables['foo'].right_only, left={}, right={'baz': ComdabColumn(...)})
- level: Literal['warning', 'error']¶
Whether the report is for an error (default) or a warning (caused by a custom rule).
- path: ComdabPath¶
The path to the difference between the two schemas.
Models¶
- class comdab.models.ComdabSchema[source]¶
A database schema, the top-level comdab model.
Equivalent to a
sqlalchemy.sql.schema.MetaDataobject.- tables: dict[str, ComdabTable]¶
- views: dict[str, ComdabView]¶
- sequences: dict[str, ComdabSequence]¶
- functions: dict[str, ComdabFunction]¶
- custom_types: dict[str, ComdabCustomType]¶
- class comdab.models.ComdabTable[source]¶
A database table.
Equivalent to a
sqlalchemy.sql.schema.Tableobject.- columns: dict[str, ComdabColumn]¶
- indexes: dict[str, ComdabIndex]¶
- triggers: dict[str, ComdabTrigger]¶
- class comdab.models.ComdabView[source]¶
A database view.
Equivalent to a
sqlalchemy.sql.schema.Tableobject.
- class comdab.models.ComdabSequence[source]¶
A database sequence.
Not natively handled by SQLAlchemy.
- class comdab.models.ComdabFunction[source]¶
A database function.
Equivalent to a
sqlalchemy.sql.functions.Functionobject.
- class comdab.models.ComdabCustomType[source]¶
A database custom type (only Enums supported).
Even types not used in any column are listed here.
- class comdab.models.ComdabColumn[source]¶
A database column.
Equivalent to a
sqlalchemy.sql.schema.Columnobject.- type: ComdabType¶
- type comdab.models.ComdabConstraint = ComdabUniqueConstraint | ComdabPrimaryKeyConstraint | ComdabForeignKeyConstraint | ComdabCheckConstraint | ComdabExcludeConstraint¶
- class comdab.models.ComdabUniqueConstraint[source]¶
A database unique constraint.
Equivalent to a
sqlalchemy.sql.schema.UniqueConstraintobject.
- class comdab.models.ComdabPrimaryKeyConstraint[source]¶
A database primary key constraint.
Equivalent to a
sqlalchemy.sql.schema.PrimaryKeyConstraintobject.
- class comdab.models.ComdabForeignKeyConstraint[source]¶
A database foreign key constraint.
Equivalent to a
sqlalchemy.sql.schema.ForeignKeyConstraintobject.
- class comdab.models.ComdabCheckConstraint[source]¶
A database check constraint.
Equivalent to a
sqlalchemy.sql.schema.CheckConstraintobject.
- class comdab.models.ComdabExcludeConstraint[source]¶
A database constraint.
Not natively handled by SQLAlchemy.
- type comdab.models.ComdabConstraintType = Literal['unique', 'primary_key', 'foreign_key', 'check', 'exclude']¶
- class comdab.models.ComdabIndex[source]¶
A database index.
Equivalent to a
sqlalchemy.sql.schema.Indexobject.
- class comdab.models.ComdabTypes[source]¶
Registry of all data types handled by comdab.
Each class member represent a database type, equivalent to a
sqlalchemy.types.TypeEngineclass.