diff options
| author | mike bayer <mike_mp@zzzcomputing.com> | 2022-08-22 13:30:36 +0000 |
|---|---|---|
| committer | Gerrit Code Review <gerrit@ci3.zzzcomputing.com> | 2022-08-22 13:30:36 +0000 |
| commit | 5c71bb51ccecefbaeec3674caaf3661d106a9549 (patch) | |
| tree | de4eaab451374fad7a937f879bfd2e125acd427d /lib/sqlalchemy/sql/events.py | |
| parent | 7842678484b9d00a64fab29cdc9e252754ac19ae (diff) | |
| parent | c5a316053d6201981240c7f8fb73934a0b241b7c (diff) | |
| download | sqlalchemy-5c71bb51ccecefbaeec3674caaf3661d106a9549.tar.gz | |
Merge "support create/drop events for all CREATE/DROP" into main
Diffstat (limited to 'lib/sqlalchemy/sql/events.py')
| -rw-r--r-- | lib/sqlalchemy/sql/events.py | 139 |
1 files changed, 118 insertions, 21 deletions
diff --git a/lib/sqlalchemy/sql/events.py b/lib/sqlalchemy/sql/events.py index 00f1e7d0d..38f460400 100644 --- a/lib/sqlalchemy/sql/events.py +++ b/lib/sqlalchemy/sql/events.py @@ -28,33 +28,98 @@ class DDLEvents(event.Events[SchemaEventTarget]): Define event listeners for schema objects, that is, :class:`.SchemaItem` and other :class:`.SchemaEventTarget` subclasses, including :class:`_schema.MetaData`, :class:`_schema.Table`, - :class:`_schema.Column`. + :class:`_schema.Column`, etc. - :class:`_schema.MetaData` and :class:`_schema.Table` support events - specifically regarding when CREATE and DROP - DDL is emitted to the database. + **Create / Drop Events** - Attachment events are also provided to customize - behavior whenever a child schema element is associated - with a parent, such as, when a :class:`_schema.Column` is associated - with its :class:`_schema.Table`, when a - :class:`_schema.ForeignKeyConstraint` - is associated with a :class:`_schema.Table`, etc. + Events emitted when CREATE and DROP commands are emitted to the database. + The event hooks in this category include :meth:`.DDLEvents.before_create`, + :meth:`.DDLEvents.after_create`, :meth:`.DDLEvents.before_drop`, and + :meth:`.DDLEvents.after_drop`. + + These events are emitted when using schema-level methods such as + :meth:`.MetaData.create_all` and :meth:`.MetaData.drop_all`. Per-object + create/drop methods such as :meth:`.Table.create`, :meth:`.Table.drop`, + :meth:`.Index.create` are also included, as well as dialect-specific + methods such as :meth:`_postgresql.ENUM.create`. - Example using the ``after_create`` event:: + .. versionadded:: 2.0 :class:`.DDLEvents` event hooks now take place + for non-table objects including constraints, indexes, and + dialect-specific schema types. + Event hooks may be attached directly to a :class:`_schema.Table` object or + to a :class:`_schema.MetaData` collection, as well as to any + :class:`.SchemaItem` class or object that can be individually created and + dropped using a distinct SQL command. Such classes include :class:`.Index`, + :class:`.Sequence`, and dialect-specific classes such as + :class:`_postgresql.ENUM`. + + Example using the :meth:`.DDLEvents.after_create` event, where a custom + event hook will emit an ``ALTER TABLE`` command on the current connection, + after ``CREATE TABLE`` is emitted:: + + from sqlalchemy import create_engine from sqlalchemy import event from sqlalchemy import Table, Column, Metadata, Integer m = MetaData() some_table = Table('some_table', m, Column('data', Integer)) + @event.listens_for(some_table, "after_create") def after_create(target, connection, **kw): connection.execute(text( "ALTER TABLE %s SET name=foo_%s" % (target.name, target.name) )) - event.listen(some_table, "after_create", after_create) + + some_engine = create_engine("postgresql://scott:tiger@host/test") + + # will emit "CREATE TABLE some_table" as well as the above + # "ALTER TABLE" statement afterwards + m.create_all(some_engine) + + Constraint objects such as :class:`.ForeignKeyConstraint`, + :class:`.UniqueConstraint`, :class:`.CheckConstraint` may also be + subscribed to these events, however they will **not** normally produce + events as these objects are usually rendered inline within an + enclosing ``CREATE TABLE`` statement and implicitly dropped from a + ``DROP TABLE`` statement. + + For the :class:`.Index` construct, the event hook will be emitted + for ``CREATE INDEX``, however SQLAlchemy does not normally emit + ``DROP INDEX`` when dropping tables as this is again implicit within the + ``DROP TABLE`` statement. + + .. versionadded:: 2.0 Support for :class:`.SchemaItem` objects + for create/drop events was expanded from its previous support for + :class:`.MetaData` and :class:`.Table` to also include + :class:`.Constraint` and all subclasses, :class:`.Index`, + :class:`.Sequence` and some type-related constructs such as + :class:`_postgresql.ENUM`. + + .. note:: These event hooks are only emitted within the scope of + SQLAlchemy's create/drop methods; they are not necessarily supported + by tools such as `alembic <https://alembic.sqlalchemy.org>`_. + + + **Attachment Events** + + Attachment events are provided to customize + behavior whenever a child schema element is associated + with a parent, such as when a :class:`_schema.Column` is associated + with its :class:`_schema.Table`, when a + :class:`_schema.ForeignKeyConstraint` + is associated with a :class:`_schema.Table`, etc. These events include + :meth:`.DDLEvents.before_parent_attach` and + :meth:`.DDLEvents.after_parent_attach`. + + **Reflection Events** + + The :meth:`.DDLEvents.column_reflect` event is used to intercept + and modify the in-Python definition of database columns when + :term:`reflection` of database tables proceeds. + + **Use with Generic DDL** DDL events integrate closely with the :class:`.DDL` class and the :class:`.ExecutableDDLElement` hierarchy @@ -68,9 +133,7 @@ class DDLEvents(event.Events[SchemaEventTarget]): DDL("ALTER TABLE %(table)s SET name=foo_%(table)s") ) - The methods here define the name of an event as well - as the names of members that are passed to listener - functions. + **Event Propagation to MetaData Copies** For all :class:`.DDLEvent` events, the ``propagate=True`` keyword argument will ensure that a given event handler is propagated to copies of the @@ -78,6 +141,10 @@ class DDLEvents(event.Events[SchemaEventTarget]): method:: from sqlalchemy import DDL + + metadata = MetaData() + some_table = Table("some_table", metadata, Column("data", Integer)) + event.listen( some_table, "after_create", @@ -85,10 +152,12 @@ class DDLEvents(event.Events[SchemaEventTarget]): propagate=True ) + new_metadata = MetaData() new_table = some_table.to_metadata(new_metadata) - The above :class:`.DDL` object will also be associated with the - :class:`_schema.Table` object represented by ``new_table``. + The above :class:`.DDL` object will be associated with the + :meth:`.DDLEvents.after_create` event for both the ``some_table`` and + the ``new_table`` :class:`.Table` objects. .. seealso:: @@ -110,8 +179,15 @@ class DDLEvents(event.Events[SchemaEventTarget]): ) -> None: r"""Called before CREATE statements are emitted. - :param target: the :class:`_schema.MetaData` or :class:`_schema.Table` + :param target: the :class:`.SchemaObject`, such as a + :class:`_schema.MetaData` or :class:`_schema.Table` + but also including all create/drop objects such as + :class:`.Index`, :class:`.Sequence`, etc., object which is the target of the event. + + .. versionadded:: 2.0 Support for all :class:`.SchemaItem` objects + was added. + :param connection: the :class:`_engine.Connection` where the CREATE statement or statements will be emitted. :param \**kw: additional keyword arguments relevant @@ -139,8 +215,15 @@ class DDLEvents(event.Events[SchemaEventTarget]): ) -> None: r"""Called after CREATE statements are emitted. - :param target: the :class:`_schema.MetaData` or :class:`_schema.Table` + :param target: the :class:`.SchemaObject`, such as a + :class:`_schema.MetaData` or :class:`_schema.Table` + but also including all create/drop objects such as + :class:`.Index`, :class:`.Sequence`, etc., object which is the target of the event. + + .. versionadded:: 2.0 Support for all :class:`.SchemaItem` objects + was added. + :param connection: the :class:`_engine.Connection` where the CREATE statement or statements have been emitted. :param \**kw: additional keyword arguments relevant @@ -163,8 +246,15 @@ class DDLEvents(event.Events[SchemaEventTarget]): ) -> None: r"""Called before DROP statements are emitted. - :param target: the :class:`_schema.MetaData` or :class:`_schema.Table` + :param target: the :class:`.SchemaObject`, such as a + :class:`_schema.MetaData` or :class:`_schema.Table` + but also including all create/drop objects such as + :class:`.Index`, :class:`.Sequence`, etc., object which is the target of the event. + + .. versionadded:: 2.0 Support for all :class:`.SchemaItem` objects + was added. + :param connection: the :class:`_engine.Connection` where the DROP statement or statements will be emitted. :param \**kw: additional keyword arguments relevant @@ -187,8 +277,15 @@ class DDLEvents(event.Events[SchemaEventTarget]): ) -> None: r"""Called after DROP statements are emitted. - :param target: the :class:`_schema.MetaData` or :class:`_schema.Table` + :param target: the :class:`.SchemaObject`, such as a + :class:`_schema.MetaData` or :class:`_schema.Table` + but also including all create/drop objects such as + :class:`.Index`, :class:`.Sequence`, etc., object which is the target of the event. + + .. versionadded:: 2.0 Support for all :class:`.SchemaItem` objects + was added. + :param connection: the :class:`_engine.Connection` where the DROP statement or statements have been emitted. :param \**kw: additional keyword arguments relevant |
