Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
events.py459 linesDownload Raw Back to sql
1# sql/events.py
2# Copyright (C) 2005-2026 the SQLAlchemy authors and contributors
3# <see AUTHORS file>
4#
5# This module is part of SQLAlchemy and is released under
6# the MIT License: https://www.opensource.org/licenses/mit-license.php
7
8from __future__ import annotations
9
10from typing import Any
11from typing import TYPE_CHECKING
12
13from .base import SchemaEventTarget
14from .. import event
15
16if TYPE_CHECKING:
17    from .schema import Column
18    from .schema import Constraint
19    from .schema import SchemaItem
20    from .schema import Table
21    from ..engine.base import Connection
22    from ..engine.interfaces import ReflectedColumn
23    from ..engine.reflection import Inspector
24
25
26class DDLEvents(event.Events[SchemaEventTarget]):
27    """
28    Define event listeners for schema objects,
29    that is, :class:`.SchemaItem` and other :class:`.SchemaEventTarget`
30    subclasses, including :class:`_schema.MetaData`, :class:`_schema.Table`,
31    :class:`_schema.Column`, etc.
32
33    **Create / Drop Events**
34
35    Events emitted when CREATE and DROP commands are emitted to the database.
36    The event hooks in this category include :meth:`.DDLEvents.before_create`,
37    :meth:`.DDLEvents.after_create`, :meth:`.DDLEvents.before_drop`, and
38    :meth:`.DDLEvents.after_drop`.
39
40    These events are emitted when using schema-level methods such as
41    :meth:`.MetaData.create_all` and :meth:`.MetaData.drop_all`. Per-object
42    create/drop methods such as :meth:`.Table.create`, :meth:`.Table.drop`,
43    :meth:`.Index.create` are also included, as well as dialect-specific
44    methods such as :meth:`_postgresql.ENUM.create`.
45
46    .. versionadded:: 2.0 :class:`.DDLEvents` event hooks now take place
47       for non-table objects including constraints, indexes, and
48       dialect-specific schema types.
49
50    Event hooks may be attached directly to a :class:`_schema.Table` object or
51    to a :class:`_schema.MetaData` collection, as well as to any
52    :class:`.SchemaItem` class or object that can be individually created and
53    dropped using a distinct SQL command. Such classes include :class:`.Index`,
54    :class:`.Sequence`, and dialect-specific classes such as
55    :class:`_postgresql.ENUM`.
56
57    Example using the :meth:`.DDLEvents.after_create` event, where a custom
58    event hook will emit an ``ALTER TABLE`` command on the current connection,
59    after ``CREATE TABLE`` is emitted::
60
61        from sqlalchemy import create_engine
62        from sqlalchemy import event
63        from sqlalchemy import Table, Column, Metadata, Integer
64
65        m = MetaData()
66        some_table = Table("some_table", m, Column("data", Integer))
67
68
69        @event.listens_for(some_table, "after_create")
70        def after_create(target, connection, **kw):
71            connection.execute(
72                text("ALTER TABLE %s SET name=foo_%s" % (target.name, target.name))
73            )
74
75
76        some_engine = create_engine("postgresql://scott:tiger@host/test")
77
78        # will emit "CREATE TABLE some_table" as well as the above
79        # "ALTER TABLE" statement afterwards
80        m.create_all(some_engine)
81
82    Constraint objects such as :class:`.ForeignKeyConstraint`,
83    :class:`.UniqueConstraint`, :class:`.CheckConstraint` may also be
84    subscribed to these events, however they will **not** normally produce
85    events as these objects are usually rendered inline within an
86    enclosing ``CREATE TABLE`` statement and implicitly dropped from a
87    ``DROP TABLE`` statement.
88
89    For the :class:`.Index` construct, the event hook will be emitted
90    for ``CREATE INDEX``, however SQLAlchemy does not normally emit
91    ``DROP INDEX`` when dropping tables as this is again implicit within the
92    ``DROP TABLE`` statement.
93
94    .. versionadded:: 2.0 Support for :class:`.SchemaItem` objects
95       for create/drop events was expanded from its previous support for
96       :class:`.MetaData` and :class:`.Table` to also include
97       :class:`.Constraint` and all subclasses, :class:`.Index`,
98       :class:`.Sequence` and some type-related constructs such as
99       :class:`_postgresql.ENUM`.
100
101    .. note:: These event hooks are only emitted within the scope of
102       SQLAlchemy's create/drop methods; they are not necessarily supported
103       by tools such as `alembic <https://alembic.sqlalchemy.org>`_.
104
105
106    **Attachment Events**
107
108    Attachment events are provided to customize
109    behavior whenever a child schema element is associated
110    with a parent, such as when a :class:`_schema.Column` is associated
111    with its :class:`_schema.Table`, when a
112    :class:`_schema.ForeignKeyConstraint`
113    is associated with a :class:`_schema.Table`, etc.  These events include
114    :meth:`.DDLEvents.before_parent_attach` and
115    :meth:`.DDLEvents.after_parent_attach`.
116
117    **Reflection Events**
118
119    The :meth:`.DDLEvents.column_reflect` event is used to intercept
120    and modify the in-Python definition of database columns when
121    :term:`reflection` of database tables proceeds.
122
123    **Use with Generic DDL**
124
125    DDL events integrate closely with the
126    :class:`.DDL` class and the :class:`.ExecutableDDLElement` hierarchy
127    of DDL clause constructs, which are themselves appropriate
128    as listener callables::
129
130        from sqlalchemy import DDL
131
132        event.listen(
133            some_table,
134            "after_create",
135            DDL("ALTER TABLE %(table)s SET name=foo_%(table)s"),
136        )
137
138    **Event Propagation to MetaData Copies**
139
140    For all :class:`.DDLEvent` events, the ``propagate=True`` keyword argument
141    will ensure that a given event handler is propagated to copies of the
142    object, which are made when using the :meth:`_schema.Table.to_metadata`
143    method::
144
145        from sqlalchemy import DDL
146
147        metadata = MetaData()
148        some_table = Table("some_table", metadata, Column("data", Integer))
149
150        event.listen(
151            some_table,
152            "after_create",
153            DDL("ALTER TABLE %(table)s SET name=foo_%(table)s"),
154            propagate=True,
155        )
156
157        new_metadata = MetaData()
158        new_table = some_table.to_metadata(new_metadata)
159
160    The above :class:`.DDL` object will be associated with the
161    :meth:`.DDLEvents.after_create` event for both the ``some_table`` and
162    the ``new_table`` :class:`.Table` objects.
163
164    .. seealso::
165
166        :ref:`event_toplevel`
167
168        :class:`.ExecutableDDLElement`
169
170        :class:`.DDL`
171
172        :ref:`schema_ddl_sequences`
173
174    """  # noqa: E501
175
176    _target_class_doc = "SomeSchemaClassOrObject"
177    _dispatch_target = SchemaEventTarget
178
179    def before_create(
180        self, target: SchemaEventTarget, connection: Connection, **kw: Any
181    ) -> None:
182        r"""Called before CREATE statements are emitted.
183
184        :param target: the :class:`.SchemaObject`, such as a
185         :class:`_schema.MetaData` or :class:`_schema.Table`
186         but also including all create/drop objects such as
187         :class:`.Index`, :class:`.Sequence`, etc.,
188         object which is the target of the event.
189
190         .. versionadded:: 2.0 Support for all :class:`.SchemaItem` objects
191            was added.
192
193        :param connection: the :class:`_engine.Connection` where the
194         CREATE statement or statements will be emitted.
195        :param \**kw: additional keyword arguments relevant
196         to the event.  The contents of this dictionary
197         may vary across releases, and include the
198         list of tables being generated for a metadata-level
199         event, the checkfirst flag, and other
200         elements used by internal events.
201
202        :func:`.event.listen` accepts the ``propagate=True``
203        modifier for this event; when True, the listener function will
204        be established for any copies made of the target object,
205        i.e. those copies that are generated when
206        :meth:`_schema.Table.to_metadata` is used.
207
208        :func:`.event.listen` accepts the ``insert=True``
209        modifier for this event; when True, the listener function will
210        be prepended to the internal list of events upon discovery, and execute
211        before registered listener functions that do not pass this argument.
212
213        """
214
215    def after_create(
216        self, target: SchemaEventTarget, connection: Connection, **kw: Any
217    ) -> None:
218        r"""Called after CREATE statements are emitted.
219
220        :param target: the :class:`.SchemaObject`, such as a
221         :class:`_schema.MetaData` or :class:`_schema.Table`
222         but also including all create/drop objects such as
223         :class:`.Index`, :class:`.Sequence`, etc.,
224         object which is the target of the event.
225
226         .. versionadded:: 2.0 Support for all :class:`.SchemaItem` objects
227            was added.
228
229        :param connection: the :class:`_engine.Connection` where the
230         CREATE statement or statements have been emitted.
231        :param \**kw: additional keyword arguments relevant
232         to the event.  The contents of this dictionary
233         may vary across releases, and include the
234         list of tables being generated for a metadata-level
235         event, the checkfirst flag, and other
236         elements used by internal events.
237
238        :func:`.event.listen` also accepts the ``propagate=True``
239        modifier for this event; when True, the listener function will
240        be established for any copies made of the target object,
241        i.e. those copies that are generated when
242        :meth:`_schema.Table.to_metadata` is used.
243
244        """
245
246    def before_drop(
247        self, target: SchemaEventTarget, connection: Connection, **kw: Any
248    ) -> None:
249        r"""Called before DROP statements are emitted.
250
251        :param target: the :class:`.SchemaObject`, such as a
252         :class:`_schema.MetaData` or :class:`_schema.Table`
253         but also including all create/drop objects such as
254         :class:`.Index`, :class:`.Sequence`, etc.,
255         object which is the target of the event.
256
257         .. versionadded:: 2.0 Support for all :class:`.SchemaItem` objects
258            was added.
259
260        :param connection: the :class:`_engine.Connection` where the
261         DROP statement or statements will be emitted.
262        :param \**kw: additional keyword arguments relevant
263         to the event.  The contents of this dictionary
264         may vary across releases, and include the
265         list of tables being generated for a metadata-level
266         event, the checkfirst flag, and other
267         elements used by internal events.
268
269        :func:`.event.listen` also accepts the ``propagate=True``
270        modifier for this event; when True, the listener function will
271        be established for any copies made of the target object,
272        i.e. those copies that are generated when
273        :meth:`_schema.Table.to_metadata` is used.
274
275        """
276
277    def after_drop(
278        self, target: SchemaEventTarget, connection: Connection, **kw: Any
279    ) -> None:
280        r"""Called after DROP statements are emitted.
281
282        :param target: the :class:`.SchemaObject`, such as a
283         :class:`_schema.MetaData` or :class:`_schema.Table`
284         but also including all create/drop objects such as
285         :class:`.Index`, :class:`.Sequence`, etc.,
286         object which is the target of the event.
287
288         .. versionadded:: 2.0 Support for all :class:`.SchemaItem` objects
289            was added.
290
291        :param connection: the :class:`_engine.Connection` where the
292         DROP statement or statements have been emitted.
293        :param \**kw: additional keyword arguments relevant
294         to the event.  The contents of this dictionary
295         may vary across releases, and include the
296         list of tables being generated for a metadata-level
297         event, the checkfirst flag, and other
298         elements used by internal events.
299
300        :func:`.event.listen` also accepts the ``propagate=True``
301        modifier for this event; when True, the listener function will
302        be established for any copies made of the target object,
303        i.e. those copies that are generated when
304        :meth:`_schema.Table.to_metadata` is used.
305
306        """
307
308    def before_parent_attach(
309        self, target: SchemaEventTarget, parent: SchemaItem
310    ) -> None:
311        """Called before a :class:`.SchemaItem` is associated with
312        a parent :class:`.SchemaItem`.
313
314        :param target: the target object
315        :param parent: the parent to which the target is being attached.
316
317        :func:`.event.listen` also accepts the ``propagate=True``
318        modifier for this event; when True, the listener function will
319        be established for any copies made of the target object,
320        i.e. those copies that are generated when
321        :meth:`_schema.Table.to_metadata` is used.
322
323        """
324
325    def after_parent_attach(
326        self, target: SchemaEventTarget, parent: SchemaItem
327    ) -> None:
328        """Called after a :class:`.SchemaItem` is associated with
329        a parent :class:`.SchemaItem`.
330
331        :param target: the target object
332        :param parent: the parent to which the target is being attached.
333
334        :func:`.event.listen` also accepts the ``propagate=True``
335        modifier for this event; when True, the listener function will
336        be established for any copies made of the target object,
337        i.e. those copies that are generated when
338        :meth:`_schema.Table.to_metadata` is used.
339
340        """
341
342    def _sa_event_column_added_to_pk_constraint(
343        self, const: Constraint, col: Column[Any]
344    ) -> None:
345        """internal event hook used for primary key naming convention
346        updates.
347
348        """
349
350    def column_reflect(
351        self, inspector: Inspector, table: Table, column_info: ReflectedColumn
352    ) -> None:
353        """Called for each unit of 'column info' retrieved when
354        a :class:`_schema.Table` is being reflected.
355
356        This event is most easily used by applying it to a specific
357        :class:`_schema.MetaData` instance, where it will take effect for
358        all :class:`_schema.Table` objects within that
359        :class:`_schema.MetaData` that undergo reflection::
360
361            metadata = MetaData()
362
363
364            @event.listens_for(metadata, "column_reflect")
365            def receive_column_reflect(inspector, table, column_info):
366                # receives for all Table objects that are reflected
367                # under this MetaData
368                ...
369
370
371            # will use the above event hook
372            my_table = Table("my_table", metadata, autoload_with=some_engine)
373
374        .. versionadded:: 1.4.0b2 The :meth:`_events.DDLEvents.column_reflect`
375           hook may now be applied to a :class:`_schema.MetaData` object as
376           well as the :class:`_schema.MetaData` class itself where it will
377           take place for all :class:`_schema.Table` objects associated with
378           the targeted :class:`_schema.MetaData`.
379
380        It may also be applied to the :class:`_schema.Table` class across
381        the board::
382
383            from sqlalchemy import Table
384
385
386            @event.listens_for(Table, "column_reflect")
387            def receive_column_reflect(inspector, table, column_info):
388                # receives for all Table objects that are reflected
389                ...
390
391        It can also be applied to a specific :class:`_schema.Table` at the
392        point that one is being reflected using the
393        :paramref:`_schema.Table.listeners` parameter::
394
395            t1 = Table(
396                "my_table",
397                autoload_with=some_engine,
398                listeners=[("column_reflect", receive_column_reflect)],
399            )
400
401        The dictionary of column information as returned by the
402        dialect is passed, and can be modified.  The dictionary
403        is that returned in each element of the list returned
404        by :meth:`.reflection.Inspector.get_columns`:
405
406            * ``name`` - the column's name, is applied to the
407              :paramref:`_schema.Column.name` parameter
408
409            * ``type`` - the type of this column, which should be an instance
410              of :class:`~sqlalchemy.types.TypeEngine`, is applied to the
411              :paramref:`_schema.Column.type` parameter
412
413            * ``nullable`` - boolean flag if the column is NULL or NOT NULL,
414              is applied to the :paramref:`_schema.Column.nullable` parameter
415
416            * ``default`` - the column's server default value.  This is
417              normally specified as a plain string SQL expression, however the
418              event can pass a :class:`.FetchedValue`, :class:`.DefaultClause`,
419              or :func:`_expression.text` object as well.  Is applied to the
420              :paramref:`_schema.Column.server_default` parameter
421
422        The event is called before any action is taken against
423        this dictionary, and the contents can be modified; the following
424        additional keys may be added to the dictionary to further modify
425        how the :class:`_schema.Column` is constructed:
426
427
428            * ``key`` - the string key that will be used to access this
429              :class:`_schema.Column` in the ``.c`` collection; will be applied
430              to the :paramref:`_schema.Column.key` parameter. Is also used
431              for ORM mapping.  See the section
432              :ref:`mapper_automated_reflection_schemes` for an example.
433
434            * ``quote`` - force or un-force quoting on the column name;
435              is applied to the :paramref:`_schema.Column.quote` parameter.
436
437            * ``info`` - a dictionary of arbitrary data to follow along with
438              the :class:`_schema.Column`, is applied to the
439              :paramref:`_schema.Column.info` parameter.
440
441        :func:`.event.listen` also accepts the ``propagate=True``
442        modifier for this event; when True, the listener function will
443        be established for any copies made of the target object,
444        i.e. those copies that are generated when
445        :meth:`_schema.Table.to_metadata` is used.
446
447        .. seealso::
448
449            :ref:`mapper_automated_reflection_schemes` -
450            in the ORM mapping documentation
451
452            :ref:`automap_intercepting_columns` -
453            in the :ref:`automap_toplevel` documentation
454
455            :ref:`metadata_reflection_dbagnostic_types` - in
456            the :ref:`metadata_reflection_toplevel` documentation
457
458        """
459 
codekingpro/portable-devtools · Team Ai