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
31 stars 5 forks source link

Error parsing PostgreSQL triggers without a `when` condition #39

Closed YaraslauZhylko closed 1 year ago

YaraslauZhylko commented 1 year ago

Trigger definition without .when() function call:

Trigger.before("insert", on="some_table", execute="on_insert_function")
.named(f"tr_some_table_on_insert")
.for_each_row()

Produced migration command:

op.execute("""CREATE TRIGGER tr_some_table_on_insert BEFORE INSERT ON some_table FOR EACH ROW EXECUTE PROCEDURE on_insert_function;""")

The migration command is correct and is successfully applied to the PostgreSQL DB.


But when I try to generate a new migration, the reflection of the previously created trigger fails:

File ".venv/lib/python3.11/site-packages/sqlalchemy_declarative_extensions/alembic/trigger.py", line 20, in _compare_triggers
    result = compare_triggers(autogen_context.connection, triggers, metadata)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.11/site-packages/sqlalchemy_declarative_extensions/trigger/compare.py", line 60, in compare_triggers
    existing_triggers = get_triggers(connection)
                        ^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.11/site-packages/sqlalchemy_declarative_extensions/sqlalchemy.py", line 31, in dispatch
    return dispatcher(connection, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.11/site-packages/sqlalchemy_declarative_extensions/dialects/postgresql/query.py", line 195, in get_triggers_postgresql
    condition=t.when.lstrip("(").rstrip(")"),
              ^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'lstrip'

The code fails here: https://github.com/DanCardin/sqlalchemy-declarative-extensions/blob/6b6e7abc2efbd97e9ec5ddd77027fea4d5f3b146/src/sqlalchemy_declarative_extensions/dialects/postgresql/query.py#L195

Because it unconditionally expects a WHEN condition and tries to process it as a string. But the condition does not exist and is set to None.

DanCardin commented 1 year ago

Thanks for the report! The Function/Trigger implementations are under utilized in comparison to some of the other features, so much appreciated (particularly for easy to fix things like this!)

Fix should be released in v0.6.6 in a few minutes

YaraslauZhylko commented 1 year ago

@DanCardin The release seems to work fine. No errors raised, no false-positive migrations generated.

Thanks for the prompt fix!