Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

task/WG-396: sqlachemy-update follow on #231

Merged
merged 7 commits into from
Dec 11, 2024
Merged
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ docker exec -it geoapi /bin/bash
# determine a description for the migration like 'add_user_email_column'
alembic revision --autogenerate -m "add_user_email_column"
# Then:
# - remove drop table commands for postgis
# - check to make sure no postgis table commands (we try to ommit them in env.py)
# - add/commit migrations
```

Expand Down
117 changes: 110 additions & 7 deletions geoapi/migrations/env.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from logging.config import fileConfig
from geoapi.db import Base
from geoapi.log import logger
from alembic import context
from geoapi.models import * # noqa: F401, F403 important to include all models for autogenerate support; do not delete
from geoapi.db import Base


# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
Expand All @@ -10,11 +13,7 @@
# This line sets up loggers basically.
fileConfig(config.config_file_name)

# add your model's MetaData object here
# for 'autogenerate' support
# from myapp import mymodel
# target_metadata = mymodel.Base.metadata

# add your model's MetaData object
target_metadata = Base.metadata

# other values from the config, defined by the needs of env.py,
Expand All @@ -23,6 +22,105 @@
# ... etc.


def include_object(object, name, type_, reflected, compare_to):
"""Filter objects for Alembic migrations, specifically handling PostGIS tables/schemas.

PostGIS manages its own schema updates through the extension system. This prevents our
application migrations from conflicting with PostGIS's internal version management and
schema updates. When PostGIS is upgraded, it will handle its own schema migrations.

"""

# Get schema info
schema = getattr(object, "schema", None)
if schema is None and type_ == "index" and hasattr(object, "table"):
schema = object.table.schema

# Tiger/PostGIS related tables and sequences to exclude
excluded_tables = [
"layer",
"topology",
"geocode_settings_default",
"street_type_lookup",
"county",
"zip_lookup_base",
"bg",
"zip_lookup",
"direction_lookup",
"state_lookup",
"featnames",
"tract",
"addrfeat",
"loader_platform",
"loader_lookuptables",
"zip_state_loc",
"tabblock",
"cousub",
"addr",
"county_lookup",
"loader_variables",
"place_lookup",
"zip_lookup_all",
"geocode_settings",
"place",
"secondary_unit_lookup",
"faces",
"pagc_lex",
"countysub_lookup",
"tabblock20",
"pagc_rules",
"edges",
"state",
"zcta5",
"zip_state",
"pagc_gaz",
]

excluded_sequences = [
"county_gid_seq",
"state_gid_seq",
"addr_gid_seq",
"edges_gid_seq",
"pagc_lex_id_seq",
"cousub_gid_seq",
"addrfeat_gid_seq",
"place_gid_seq",
"bg_gid_seq",
"faces_gid_seq",
"pagc_rules_id_seq",
"tabblock_gid_seq",
"tract_gid_seq",
"featnames_gid_seq",
"zcta5_gid_seq",
"pagc_gaz_id_seq",
]

# Check schemas first
if schema in ["tiger", "topology"]:
logger.info(f"Excluding {type_} {name} due to schema {schema}")
return False

# Check type-specific exclusions
if type_ == "table":
if name == "spatial_ref_sys" or name.lower() in excluded_tables:
logger.info(f"Excluding table {name}")
return False

elif type_ == "index" and hasattr(object, "table"):
table_name = object.table.name.lower()
if table_name in excluded_tables:
logger.info(f"Excluding index {name} for excluded table {table_name}")
return False

elif type_ == "sequence":
if name.lower() in excluded_sequences:
logger.info(f"Excluding sequence {name}")
return False

logger.info(f"Including {type_} {name}")
return True


def run_migrations_offline():
"""Run migrations in 'offline' mode.

Expand All @@ -41,6 +139,7 @@ def run_migrations_offline():
target_metadata=target_metadata,
literal_binds=True,
dialect_opts={"paramstyle": "named"},
include_object=include_object,
)

with context.begin_transaction():
Expand All @@ -63,7 +162,11 @@ def run_migrations_online():
# )

with engine.connect() as connection:
context.configure(connection=connection, target_metadata=target_metadata)
context.configure(
connection=connection,
target_metadata=target_metadata,
include_object=include_object,
)

with context.begin_transaction():
context.run_migrations()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"""Add migration of spatial index

Revision ID: f2d7f797c82a
Revises: 968f358e102a
Create Date: 2024-12-11 03:51:58.509951

"""

from alembic import op


# revision identifiers, used by Alembic.
revision = "f2d7f797c82a"
down_revision = "968f358e102a"
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_index(
"idx_features_the_geom",
"features",
["the_geom"],
unique=False,
postgresql_using="gist",
)
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index(
"idx_features_the_geom", table_name="features", postgresql_using="gist"
)
# ### end Alembic commands ###
4 changes: 3 additions & 1 deletion geoapi/models/feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ class Feature(Base):
project_id = Column(
ForeignKey("projects.id", ondelete="CASCADE", onupdate="CASCADE"), index=True
)
the_geom = Column(Geometry(geometry_type="GEOMETRY", srid=4326), nullable=False)
the_geom = Column(
Geometry(geometry_type="GEOMETRY", srid=4326), nullable=False
) # Spatial index included by default
properties = Column(JSONB, default={})
styles = Column(JSONB, default={})
created_date = Column(DateTime(timezone=True), server_default=func.now())
Expand Down
Loading