Skip to content

Commit

Permalink
Add automatic naming conventions for database relations (#138)
Browse files Browse the repository at this point in the history
  • Loading branch information
uittenbroekrobbert authored Aug 13, 2024
2 parents 3f68457 + 8750524 commit 3c58081
Show file tree
Hide file tree
Showing 7 changed files with 25 additions and 34 deletions.
2 changes: 1 addition & 1 deletion BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ poetry install
When poetry is done installing all dependencies you can start using the tool.

```shell
poetry run python -m uvicorn amt.main:app --log-level warning
poetry run python -m uvicorn amt.server:app --log-level warning
```

### Suggested development ENVIRONMENT settings
Expand Down
2 changes: 1 addition & 1 deletion amt/api/deps.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def _create_env(
directory: str | PathLike[typing.AnyStr] | typing.Sequence[str | PathLike[typing.AnyStr]],
**env_options: typing.Any, # noqa: ANN401
) -> Environment:
env: Environment = super()._create_env(directory, **env_options) # pyright: ignore [reportUnknownMemberType, reportUnknownVariableType]
env: Environment = super()._create_env(directory, **env_options) # pyright: ignore [reportUnknownMemberType, reportUnknownVariableType, reportArgumentType]
env.add_extension("jinja2.ext.i18n") # pyright: ignore [reportUnknownMemberType]
return env # pyright: ignore [reportUnknownVariableType]

Expand Down
4 changes: 3 additions & 1 deletion amt/migrations/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
from sqlalchemy import engine_from_config, pool
from sqlalchemy.schema import MetaData

from amt.models.base import Base

config = context.config

if config.config_file_name is not None:
fileConfig(config.config_file_name)

target_metadata = MetaData()
target_metadata = Base.metadata


def get_url() -> str:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,14 @@


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table("task", schema=None) as batch_op:
batch_op.add_column(sa.Column("project_id", sa.Integer(), nullable=True))
batch_op.create_foreign_key("fk_project_id", "project", ["project_id"], ["id"])

# ### end Alembic commands ###
# Note that the value None below is due to the automatic naming generation from Base.metadata
batch_op.create_foreign_key(None, "project", ["project_id"], ["id"])


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table("task", schema=None) as batch_op:
batch_op.drop_constraint("fk_project_id", type_="foreignkey")
# Drop constraint in batch mode lacks the fields to use automatic naming convention
batch_op.drop_constraint("fk_task_project_id_project", type_="foreignkey")
batch_op.drop_column("project_id")

# ### end Alembic commands ###
24 changes: 4 additions & 20 deletions amt/migrations/versions/9ce2341f2922_remove_the_status_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,15 @@


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
# fix unnamed foreign keys:
# https://alembic.sqlalchemy.org/en/latest/batch.html#dropping-unnamed-or-named-foreign-key-constraints
naming_convention = {
"fk":
"%(table_name)s_%(column_0_name)s_fkey"
}
with op.batch_alter_table("task", naming_convention=naming_convention) as batch_op:
with op.batch_alter_table("task") as batch_op:
batch_op.drop_constraint(
"task_status_id_fkey", type_="foreignkey")
"fk_task_status_id_status", type_="foreignkey")

op.drop_table("status")
# ### end Alembic commands ###


def downgrade() -> None:

naming_convention = {
"fk":
"%(table_name)s_%(column_0_name)s_fkey"
}

op.create_table(
"status",
sa.Column("id", sa.Integer(), nullable=False),
Expand All @@ -51,8 +38,5 @@ def downgrade() -> None:

op.execute("UPDATE task SET status_id = NULL")

# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table("task", naming_convention=naming_convention) as batch_op:
batch_op.create_foreign_key("task_status_id_fkey", "status", ["status_id"], ["id"])

# ### end Alembic commands ###
with op.batch_alter_table("task") as batch_op:
batch_op.create_foreign_key(None, "status", ["status_id"], ["id"])
11 changes: 10 additions & 1 deletion amt/models/base.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
from sqlalchemy import MetaData
from sqlalchemy.orm import DeclarativeBase


class Base(DeclarativeBase):
pass
metadata = MetaData(
naming_convention={
"ix": "ix_%(column_0_label)s",
"uq": "uq_%(table_name)s_%(column_0_name)s",
"ck": "ck_%(table_name)s_`%(constraint_name)s`",
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
"pk": "pk_%(table_name)s",
}
)
4 changes: 2 additions & 2 deletions tests/site/static/templates/test_task_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ def test_template_rendering():
"""
# todo (robbert) there is probably a better way to clean results than replacing newlines and spaces
# and we probably would want a function for it
cleaned_results = result.body.decode().replace("\n", "").replace(" ", "")
cleaned_expected_result = expected_result.replace("\n", "").replace(" ", "")
cleaned_results: str = result.body.decode().replace("\n", "").replace(" ", "") # pyright: ignore [reportUnknownMemberType, reportUnknownVariableType, reportAttributeAccessIssue]
cleaned_expected_result: str = expected_result.replace("\n", "").replace(" ", "")
assert cleaned_results == cleaned_expected_result

0 comments on commit 3c58081

Please sign in to comment.