I'm working on a project that uses SQLite as a database and Alembic as a database migration tool. It includes spatial data and therefore, spatial extensions and geoalchemy2
are included in the project. I'm using autogenerate
command and it detects some changes that don't exist in the geometry columns.
Here is the simplified structure of the project:
# Model
sqlite_naming_convention = {
"ix": "ix_%(column_0_label)s",
"uq": "uq_%(table_name)s_%(column_0_name)s",
"ck": "ck_%(table_name)s_%(column_0_name)s",
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
"pk": "pk_%(table_name)s",
}
Metadata = MetaData(naming_convention=sqlite_naming_convention)
BaseSpatiaLite = declarative_base(metadata=Metadata)
class Geometries(BaseSpatiaLite):
__tablename__ = "Geometries"
geometry_id = Column(Integer, primary_key=True)
geometry = Column(
geoalchemy2.types.Geometry(geometry_type="GEOMETRY", srid=4326, management=True),
nullable=False,
)
name = Column(String(length=150), nullable=False)
Alembic's env.py
is as follows:
# env.py
...
def run_migrations_online():
connectable = engine_from_config(
config.get_section(config.config_ini_section),
prefix="sqlalchemy.",
poolclass=pool.NullPool,
)
# Enables Spatialite extension
listen(connectable, "connect", load_spatialite)
# Creates Spatial tables if they don't exist
create_spatial_tables_for_sqlite(connectable)
with connectable.connect() as connection:
context.configure(
connection=connection,
target_metadata=target_metadata,
render_as_batch=True,
compare_type=True,
)
with context.begin_transaction():
context.run_migrations()
First migration script which creates the Geometry table:
...
def upgrade():
op.create_table(
"Geometries",
sa.Column("geometry_id", sa.Integer(), nullable=False),
sa.Column("geometry", geoalchemy2.types.Geometry(management=True), nullable=False),
sa.Column("name", sa.String(length=150), nullable=False),
sa.PrimaryKeyConstraint("geometry_id"),
)
def downgrade():
op.drop_table(
"Geometries",
)
After this migration script is run, the table is created correctly:
When I run autogenerate
command again, it should have found no changes. However, it generates a migration script which has an arbitrary type change:
def upgrade():
with op.batch_alter_table("Geometries", schema=None) as batch_op:
batch_op.alter_column(
"geometry",
existing_type=sa.NUMERIC(),
type_=geoalchemy2.types.Geometry(srid=4326, management=True),
nullable=False,
)
def downgrade():
with op.batch_alter_table("Geometries", schema=None) as batch_op:
batch_op.alter_column(
"geometry",
existing_type=geoalchemy2.types.Geometry(srid=4326, management=True),
type_=sa.NUMERIC(),
nullable=True,
)
I know that I might set compare_type
argument to False
but I'd like to auto-detect the type changes. Is there any way to tell Alembic that the type of geometry
column is Geometry
and there is no change at all?