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