diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2009-10-12 00:11:00 +0000 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2009-10-12 00:11:00 +0000 |
| commit | d6239f2262f44cdf1c87d2ded28d0fe45ad8963d (patch) | |
| tree | 9bca598e26cbd0108a9ab9d9419fc697f1024bc8 /lib/sqlalchemy | |
| parent | 114ad36894ab37280106feb15e5421ac124c6834 (diff) | |
| download | sqlalchemy-d6239f2262f44cdf1c87d2ded28d0fe45ad8963d.tar.gz | |
- added "ddl" argument to the "on" callable of DDLElement [ticket:1538]
- fixed the imports in the "postgres" cleanup dialect
- renamed "schema_item" attribute/argument of DDLElement
to "target".
Diffstat (limited to 'lib/sqlalchemy')
| -rw-r--r-- | lib/sqlalchemy/dialects/postgres.py | 3 | ||||
| -rw-r--r-- | lib/sqlalchemy/schema.py | 105 | ||||
| -rw-r--r-- | lib/sqlalchemy/sql/compiler.py | 6 |
3 files changed, 60 insertions, 54 deletions
diff --git a/lib/sqlalchemy/dialects/postgres.py b/lib/sqlalchemy/dialects/postgres.py index e66989fa7..0c1d3fd25 100644 --- a/lib/sqlalchemy/dialects/postgres.py +++ b/lib/sqlalchemy/dialects/postgres.py @@ -6,4 +6,5 @@ warn_deprecated( "The new URL format is postgresql[+driver]://<user>:<pass>@<host>/<dbname>" ) -from sqlalchemy.dialects.postgresql import *
\ No newline at end of file +from sqlalchemy.dialects.postgresql import * +from sqlalchemy.dialects.postgresql import base diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py index b91764da1..845459e81 100644 --- a/lib/sqlalchemy/schema.py +++ b/lib/sqlalchemy/schema.py @@ -360,7 +360,7 @@ class Table(SchemaItem, expression.TableClause): event The event currently being handled - schema_item + target The ``Table`` object being created or dropped bind The ``Connection`` bueing used for DDL execution. @@ -1250,10 +1250,12 @@ class Constraint(SchemaItem): @property def table(self): - if isinstance(self.parent, Table): - return self.parent - else: - raise exc.InvalidRequestError("This constraint is not bound to a table.") + try: + if isinstance(self.parent, Table): + return self.parent + except AttributeError: + pass + raise exc.InvalidRequestError("This constraint is not bound to a table. Did you mean to call table.add_constraint(constraint) ?") def _set_parent(self, parent): self.parent = parent @@ -1451,7 +1453,7 @@ class ForeignKeyConstraint(Constraint): fk._set_parent(col) if self.use_alter: - def supports_alter(event, schema_item, bind, **kw): + def supports_alter(ddl, event, schema_item, bind, **kw): return table in set(kw['tables']) and bind.dialect.supports_alter AddConstraint(self, on=supports_alter).execute_at('after-create', table.metadata) DropConstraint(self, on=supports_alter).execute_at('before-drop', table.metadata) @@ -1770,7 +1772,7 @@ class MetaData(SchemaItem): event The event currently being handled - schema_item + target The ``MetaData`` object being operated upon bind The ``Connection`` bueing used for DDL execution. @@ -1917,10 +1919,10 @@ class DDLElement(expression.ClauseElement): supports_execution = True _autocommit = True - schema_item = None + target = None on = None - def execute(self, bind=None, schema_item=None): + def execute(self, bind=None, target=None): """Execute this DDL immediately. Executes the DDL statement in isolation using the supplied @@ -1932,24 +1934,25 @@ class DDLElement(expression.ClauseElement): Optional, an ``Engine`` or ``Connection``. If not supplied, a valid :class:`~sqlalchemy.engine.base.Connectable` must be present in the ``.bind`` property. - schema_item - Optional, defaults to None. Will be passed to the ``on`` callable - criteria, if any, and may provide string expansion data for the + target + Optional, defaults to None. The target SchemaItem for the + execute call. Will be passed to the ``on`` callable if any, + and may also provide string expansion data for the statement. See ``execute_at`` for more information. """ if bind is None: bind = _bind_or_error(self) - if self._should_execute(None, schema_item, bind): - return bind.execute(self.against(schema_item)) + if self._should_execute(None, target, bind): + return bind.execute(self.against(target)) else: bind.engine.logger.info("DDL execution skipped, criteria not met.") - def execute_at(self, event, schema_item): + def execute_at(self, event, target): """Link execution of this DDL to the DDL lifecycle of a SchemaItem. - Links this ``DDL`` to a ``Table`` or ``MetaData`` instance, executing + Links this ``DDLElement`` to a ``Table`` or ``MetaData`` instance, executing it when that schema item is created or dropped. The DDL statement will be executed using the same Connection and transactional context as the Table create/drop itself. The ``.bind`` property of this @@ -1959,23 +1962,11 @@ class DDLElement(expression.ClauseElement): One of the events defined in the schema item's ``.ddl_events``; e.g. 'before-create', 'after-create', 'before-drop' or 'after-drop' - schema_item - A Table or MetaData instance - - When operating on Table events, the following additional ``statement`` - string substitions are available:: + target + The Table or MetaData instance for which this DDLElement will + be associated with. - %(table)s - the Table name, with any required quoting applied - %(schema)s - the schema name, with any required quoting applied - %(fullname)s - the Table name including schema, quoted if needed - - The DDL's ``context``, if any, will be combined with the standard - substutions noted above. Keys present in the context will override - the standard substitutions. - - A DDL instance can be linked to any number of schema items. The - statement subsitution support allows for DDL instances to be used in a - template fashion. + A DDLElement instance can be linked to any number of schema items. ``execute_at`` builds on the ``append_ddl_listener`` interface of MetaDta and Table objects. @@ -1985,27 +1976,27 @@ class DDLElement(expression.ClauseElement): in a future release. """ - if not hasattr(schema_item, 'ddl_listeners'): + if not hasattr(target, 'ddl_listeners'): raise exc.ArgumentError( - "%s does not support DDL events" % type(schema_item).__name__) - if event not in schema_item.ddl_events: + "%s does not support DDL events" % type(target).__name__) + if event not in target.ddl_events: raise exc.ArgumentError( "Unknown event, expected one of (%s), got '%r'" % - (', '.join(schema_item.ddl_events), event)) - schema_item.ddl_listeners[event].append(self) + (', '.join(target.ddl_events), event)) + target.ddl_listeners[event].append(self) return self @expression._generative - def against(self, schema_item): + def against(self, target): """Return a copy of this DDL against a specific schema item.""" - self.schema_item = schema_item + self.target = target - def __call__(self, event, schema_item, bind, **kw): + def __call__(self, event, target, bind, **kw): """Execute the DDL as a ddl_listener.""" - if self._should_execute(event, schema_item, bind, **kw): - return bind.execute(self.against(schema_item)) + if self._should_execute(event, target, bind, **kw): + return bind.execute(self.against(target)) def _check_ddl_on(self, on): if (on is not None and @@ -2014,7 +2005,7 @@ class DDLElement(expression.ClauseElement): "Expected the name of a database dialect, a tuple of names, or a callable for " "'on' criteria, got type '%s'." % type(on).__name__) - def _should_execute(self, event, schema_item, bind, **kw): + def _should_execute(self, event, target, bind, **kw): if self.on is None: return True elif isinstance(self.on, basestring): @@ -2022,7 +2013,7 @@ class DDLElement(expression.ClauseElement): elif isinstance(self.on, (tuple, list, set)): return bind.engine.name in self.on else: - return self.on(event, schema_item, bind, **kw) + return self.on(self, event, target, bind, **kw) def bind(self): if self._bind: @@ -2060,7 +2051,18 @@ class DDL(DDLElement): drop_spow = DDL('ALTER TABLE users SET secretpowers FALSE') connection.execute(drop_spow) - + + When operating on Table events, the following ``statement`` + string substitions are available:: + + %(table)s - the Table name, with any required quoting applied + %(schema)s - the schema name, with any required quoting applied + %(fullname)s - the Table name including schema, quoted if needed + + The DDL's ``context``, if any, will be combined with the standard + substutions noted above. Keys present in the context will override + the standard substitutions. + """ __visit_name__ = "ddl" @@ -2088,16 +2090,19 @@ class DDL(DDLElement): DDL('something', on=('postgresql', 'mysql')) - If a callable, it will be invoked with three positional arguments + If a callable, it will be invoked with four positional arguments as well as optional keyword arguments: - + + ddl + This DDL element. + event The name of the event that has triggered this DDL, such as 'after-create' Will be None if the DDL is executed explicitly. - schema_item - A SchemaItem instance, such as ``Table`` or ``MetaData``. May be - None if the DDL is executed explicitly. + target + The ``Table`` or ``MetaData`` object which is the target of + this event. May be None if the DDL is executed explicitly. connection The ``Connection`` being used for DDL execution diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index b4b901067..4cf4bd869 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -922,11 +922,11 @@ class DDLCompiler(engine.Compiled): def visit_ddl(self, ddl, **kwargs): # table events can substitute table and schema name context = ddl.context - if isinstance(ddl.schema_item, schema.Table): + if isinstance(ddl.target, schema.Table): context = context.copy() preparer = self.dialect.identifier_preparer - path = preparer.format_table_seq(ddl.schema_item) + path = preparer.format_table_seq(ddl.target) if len(path) == 1: table, sch = path[0], '' else: @@ -934,7 +934,7 @@ class DDLCompiler(engine.Compiled): context.setdefault('table', table) context.setdefault('schema', sch) - context.setdefault('fullname', preparer.format_table(ddl.schema_item)) + context.setdefault('fullname', preparer.format_table(ddl.target)) return ddl.statement % context |
