table.tometadata(...) doesn't copy event handlers

Issue #4179 resolved
Chris Withers
created an issue

I added some custom DDL to a table definition as follows:

event.listen(
    Observation.__table__,
    'after_create',
    DDL(
        'alter table observation add constraint observation_best ...'
    )
)

...but it wasn't firing, not even an exception when I deliberately misspelled the table name ;-)

Tracked it down to this class I use to allow one schema to be managed by multiple python packages:

https://github.com/Mortar/mortar_rdb/blob/master/mortar_rdb/controlled.py#L59

This line in particular:

https://github.com/Mortar/mortar_rdb/blob/master/mortar_rdb/controlled.py#L81

It appears that call isn't carrying the event handlers across to the table created in the new metadata object. For my use case, it needs to, but I appreciate my use case may well be a bit of an edge case.

Comments (14)

  1. Michael Bayer repo owner

    I've got nothing quick on this, this would have to be some kind of all-new feature, "copy_events=True" - the DDL() object you're using isn't associated with the Table in any official way, it is not "copied" the way a Constraint or an Index would be, and moving the events automatically is not part of the usage contract (though I can see how it would be useful). "copy_events" would also not be able to make an actual "copy" of the listener itself which is usually just a Python function, it could "copy" the DDL() object but it would prefer to be consistent.

  2. Michael Bayer repo owner

    better idea, make it a kwarg of the events themselves, so this can be determined on the event side:

    event.listen(
        Observation.__table__,
        'after_create',
        DDL(
            'alter table observation add constraint observation_best ...'
        ), copy_with_target=True
    )
    
  3. Michael Bayer repo owner

    internals are pretty nasty on this one. I'd recommend for now either going forward with the ExcludeConstraint() patch you were going to do ( :) ), or adding your DDL() to the table.info as well and then re-associating it when you call upon tometadata().

  4. Michael Bayer repo owner

    wow #$^$% me. I was thinking to use "propagate" for this "new" feature and then figured, nah that's not quite it... but, it is:

    event.listen(
        A.__table__,
        'after_create',
        DDL("foo bar"),
        propagate=True
    )
    
  5. Log in to comment