events.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. # sqlalchemy/sql/events.py
  2. # Copyright (C) 2005-2022 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. from .base import SchemaEventTarget
  8. from .. import event
  9. class DDLEvents(event.Events):
  10. """
  11. Define event listeners for schema objects,
  12. that is, :class:`.SchemaItem` and other :class:`.SchemaEventTarget`
  13. subclasses, including :class:`_schema.MetaData`, :class:`_schema.Table`,
  14. :class:`_schema.Column`.
  15. :class:`_schema.MetaData` and :class:`_schema.Table` support events
  16. specifically regarding when CREATE and DROP
  17. DDL is emitted to the database.
  18. Attachment events are also provided to customize
  19. behavior whenever a child schema element is associated
  20. with a parent, such as, when a :class:`_schema.Column` is associated
  21. with its :class:`_schema.Table`, when a
  22. :class:`_schema.ForeignKeyConstraint`
  23. is associated with a :class:`_schema.Table`, etc.
  24. Example using the ``after_create`` event::
  25. from sqlalchemy import event
  26. from sqlalchemy import Table, Column, Metadata, Integer
  27. m = MetaData()
  28. some_table = Table('some_table', m, Column('data', Integer))
  29. def after_create(target, connection, **kw):
  30. connection.execute(text(
  31. "ALTER TABLE %s SET name=foo_%s" % (target.name, target.name)
  32. ))
  33. event.listen(some_table, "after_create", after_create)
  34. DDL events integrate closely with the
  35. :class:`.DDL` class and the :class:`.DDLElement` hierarchy
  36. of DDL clause constructs, which are themselves appropriate
  37. as listener callables::
  38. from sqlalchemy import DDL
  39. event.listen(
  40. some_table,
  41. "after_create",
  42. DDL("ALTER TABLE %(table)s SET name=foo_%(table)s")
  43. )
  44. The methods here define the name of an event as well
  45. as the names of members that are passed to listener
  46. functions.
  47. For all :class:`.DDLEvent` events, the ``propagate=True`` keyword argument
  48. will ensure that a given event handler is propagated to copies of the
  49. object, which are made when using the :meth:`_schema.Table.to_metadata`
  50. method::
  51. from sqlalchemy import DDL
  52. event.listen(
  53. some_table,
  54. "after_create",
  55. DDL("ALTER TABLE %(table)s SET name=foo_%(table)s"),
  56. propagate=True
  57. )
  58. new_table = some_table.to_metadata(new_metadata)
  59. The above :class:`.DDL` object will also be associated with the
  60. :class:`_schema.Table` object represented by ``new_table``.
  61. .. seealso::
  62. :ref:`event_toplevel`
  63. :class:`.DDLElement`
  64. :class:`.DDL`
  65. :ref:`schema_ddl_sequences`
  66. """
  67. _target_class_doc = "SomeSchemaClassOrObject"
  68. _dispatch_target = SchemaEventTarget
  69. def before_create(self, target, connection, **kw):
  70. r"""Called before CREATE statements are emitted.
  71. :param target: the :class:`_schema.MetaData` or :class:`_schema.Table`
  72. object which is the target of the event.
  73. :param connection: the :class:`_engine.Connection` where the
  74. CREATE statement or statements will be emitted.
  75. :param \**kw: additional keyword arguments relevant
  76. to the event. The contents of this dictionary
  77. may vary across releases, and include the
  78. list of tables being generated for a metadata-level
  79. event, the checkfirst flag, and other
  80. elements used by internal events.
  81. :func:`.event.listen` accepts the ``propagate=True``
  82. modifier for this event; when True, the listener function will
  83. be established for any copies made of the target object,
  84. i.e. those copies that are generated when
  85. :meth:`_schema.Table.to_metadata` is used.
  86. :func:`.event.listen` accepts the ``insert=True``
  87. modifier for this event; when True, the listener function will
  88. be prepended to the internal list of events upon discovery, and execute
  89. before registered listener functions that do not pass this argument.
  90. """
  91. def after_create(self, target, connection, **kw):
  92. r"""Called after CREATE statements are emitted.
  93. :param target: the :class:`_schema.MetaData` or :class:`_schema.Table`
  94. object which is the target of the event.
  95. :param connection: the :class:`_engine.Connection` where the
  96. CREATE statement or statements have been emitted.
  97. :param \**kw: additional keyword arguments relevant
  98. to the event. The contents of this dictionary
  99. may vary across releases, and include the
  100. list of tables being generated for a metadata-level
  101. event, the checkfirst flag, and other
  102. elements used by internal events.
  103. :func:`.event.listen` also accepts the ``propagate=True``
  104. modifier for this event; when True, the listener function will
  105. be established for any copies made of the target object,
  106. i.e. those copies that are generated when
  107. :meth:`_schema.Table.to_metadata` is used.
  108. """
  109. def before_drop(self, target, connection, **kw):
  110. r"""Called before DROP statements are emitted.
  111. :param target: the :class:`_schema.MetaData` or :class:`_schema.Table`
  112. object which is the target of the event.
  113. :param connection: the :class:`_engine.Connection` where the
  114. DROP statement or statements will be emitted.
  115. :param \**kw: additional keyword arguments relevant
  116. to the event. The contents of this dictionary
  117. may vary across releases, and include the
  118. list of tables being generated for a metadata-level
  119. event, the checkfirst flag, and other
  120. elements used by internal events.
  121. :func:`.event.listen` also accepts the ``propagate=True``
  122. modifier for this event; when True, the listener function will
  123. be established for any copies made of the target object,
  124. i.e. those copies that are generated when
  125. :meth:`_schema.Table.to_metadata` is used.
  126. """
  127. def after_drop(self, target, connection, **kw):
  128. r"""Called after DROP statements are emitted.
  129. :param target: the :class:`_schema.MetaData` or :class:`_schema.Table`
  130. object which is the target of the event.
  131. :param connection: the :class:`_engine.Connection` where the
  132. DROP statement or statements have been emitted.
  133. :param \**kw: additional keyword arguments relevant
  134. to the event. The contents of this dictionary
  135. may vary across releases, and include the
  136. list of tables being generated for a metadata-level
  137. event, the checkfirst flag, and other
  138. elements used by internal events.
  139. :func:`.event.listen` also accepts the ``propagate=True``
  140. modifier for this event; when True, the listener function will
  141. be established for any copies made of the target object,
  142. i.e. those copies that are generated when
  143. :meth:`_schema.Table.to_metadata` is used.
  144. """
  145. def before_parent_attach(self, target, parent):
  146. """Called before a :class:`.SchemaItem` is associated with
  147. a parent :class:`.SchemaItem`.
  148. :param target: the target object
  149. :param parent: the parent to which the target is being attached.
  150. :func:`.event.listen` also accepts the ``propagate=True``
  151. modifier for this event; when True, the listener function will
  152. be established for any copies made of the target object,
  153. i.e. those copies that are generated when
  154. :meth:`_schema.Table.to_metadata` is used.
  155. """
  156. def after_parent_attach(self, target, parent):
  157. """Called after a :class:`.SchemaItem` is associated with
  158. a parent :class:`.SchemaItem`.
  159. :param target: the target object
  160. :param parent: the parent to which the target is being attached.
  161. :func:`.event.listen` also accepts the ``propagate=True``
  162. modifier for this event; when True, the listener function will
  163. be established for any copies made of the target object,
  164. i.e. those copies that are generated when
  165. :meth:`_schema.Table.to_metadata` is used.
  166. """
  167. def _sa_event_column_added_to_pk_constraint(self, const, col):
  168. """internal event hook used for primary key naming convention
  169. updates.
  170. """
  171. def column_reflect(self, inspector, table, column_info):
  172. """Called for each unit of 'column info' retrieved when
  173. a :class:`_schema.Table` is being reflected.
  174. This event is most easily used by applying it to a specific
  175. :class:`_schema.MetaData` instance, where it will take effect for
  176. all :class:`_schema.Table` objects within that
  177. :class:`_schema.MetaData` that undergo reflection::
  178. metadata = MetaData()
  179. @event.listens_for(metadata, 'column_reflect')
  180. def receive_column_reflect(inspector, table, column_info):
  181. # receives for all Table objects that are reflected
  182. # under this MetaData
  183. # will use the above event hook
  184. my_table = Table("my_table", metadata, autoload_with=some_engine)
  185. .. versionadded:: 1.4.0b2 The :meth:`_events.DDLEvents.column_reflect`
  186. hook may now be applied to a :class:`_schema.MetaData` object as
  187. well as the :class:`_schema.MetaData` class itself where it will
  188. take place for all :class:`_schema.Table` objects associated with
  189. the targeted :class:`_schema.MetaData`.
  190. It may also be applied to the :class:`_schema.Table` class across
  191. the board::
  192. from sqlalchemy import Table
  193. @event.listens_for(Table, 'column_reflect')
  194. def receive_column_reflect(inspector, table, column_info):
  195. # receives for all Table objects that are reflected
  196. It can also be applied to a specific :class:`_schema.Table` at the
  197. point that one is being reflected using the
  198. :paramref:`_schema.Table.listeners` parameter::
  199. t1 = Table(
  200. "my_table",
  201. autoload_with=some_engine,
  202. listeners=[
  203. ('column_reflect', receive_column_reflect)
  204. ]
  205. )
  206. A future release will allow it to be associated with a specific
  207. :class:`_schema.MetaData` object as well.
  208. The dictionary of column information as returned by the
  209. dialect is passed, and can be modified. The dictionary
  210. is that returned in each element of the list returned
  211. by :meth:`.reflection.Inspector.get_columns`:
  212. * ``name`` - the column's name, is applied to the
  213. :paramref:`_schema.Column.name` parameter
  214. * ``type`` - the type of this column, which should be an instance
  215. of :class:`~sqlalchemy.types.TypeEngine`, is applied to the
  216. :paramref:`_schema.Column.type` parameter
  217. * ``nullable`` - boolean flag if the column is NULL or NOT NULL,
  218. is applied to the :paramref:`_schema.Column.nullable` parameter
  219. * ``default`` - the column's server default value. This is
  220. normally specified as a plain string SQL expression, however the
  221. event can pass a :class:`.FetchedValue`, :class:`.DefaultClause`,
  222. or :func:`_expression.text` object as well. Is applied to the
  223. :paramref:`_schema.Column.server_default` parameter
  224. The event is called before any action is taken against
  225. this dictionary, and the contents can be modified; the following
  226. additional keys may be added to the dictionary to further modify
  227. how the :class:`_schema.Column` is constructed:
  228. * ``key`` - the string key that will be used to access this
  229. :class:`_schema.Column` in the ``.c`` collection; will be applied
  230. to the :paramref:`_schema.Column.key` parameter. Is also used
  231. for ORM mapping. See the section
  232. :ref:`mapper_automated_reflection_schemes` for an example.
  233. * ``quote`` - force or un-force quoting on the column name;
  234. is applied to the :paramref:`_schema.Column.quote` parameter.
  235. * ``info`` - a dictionary of arbitrary data to follow along with
  236. the :class:`_schema.Column`, is applied to the
  237. :paramref:`_schema.Column.info` parameter.
  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. .. seealso::
  244. :ref:`mapper_automated_reflection_schemes` -
  245. in the ORM mapping documentation
  246. :ref:`automap_intercepting_columns` -
  247. in the :ref:`automap_toplevel` documentation
  248. :ref:`metadata_reflection_dbagnostic_types` - in
  249. the :ref:`metadata_reflection_toplevel` documentation
  250. """