DanCardin / sqlalchemy-declarative-extensions

Library to declare additional kinds of objects not natively supported by SqlAlchemy/Alembic.
https://sqlalchemy-declarative-extensions.readthedocs.io/en/latest/
Apache License 2.0
36 stars 7 forks source link

Alembic audit table updates #54

Closed PJansson closed 7 months ago

PJansson commented 7 months ago

I am testing the following setup:

@declarative_database
class Base(DeclarativeBase):
    schemas = Schemas().are('audit')

user_table = Table(
    'user_account',
    Base.metadata,
    Column('id', Integer, primary_key=True),
    Column('name', String(30)),
)

audit_table(user_table, schema='audit')

Then I have set target_metadata = Base.metadata and register_alembic_events() in my alembic env.py.

This works as expected for the first migration but lets say I add a new column to the user_account table and autogenerate a new alembic revision it will try create a new user_account_audit table and its triggers instead of updating the existing ones. Is there a way to have alembic update the audit table and the corresponding triggers automatically?

DanCardin commented 7 months ago

I'm reasonably sure I can reproduce the issue you're having, but it's more an issue/side-effect of alembic, i think.

Table autogeneration is handled natively by alembic. you're defining a schema and referencing it with alembic, but natively for tables, alembic requires you set:

    context.configure(
        connection=connection,
        target_metadata=target_metadata,
        include_schemas=True
    )

In order to track things in anything but the default (public) schema. After that, the table behavior works as expected. I'm guessing this is the same behavior you'd see if you had manually defined the table yourself.


The functions/triggers are getting CREATE OR REPLACE'd which I believe is unavoidable, and shouldnt result in any issues

PJansson commented 7 months ago

Ah yeah, you are correct! I was under the impression that alembic would also handle tracking for everything its able to create, quite weird to have one but the other. Simply including schemas in env.py did the trick, thank you!