]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Table.create() and Table.drop() no longer apply metadata-
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 16 Apr 2010 17:08:45 +0000 (13:08 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 16 Apr 2010 17:08:45 +0000 (13:08 -0400)
level create/drop events.  [ticket:1771]

CHANGES
lib/sqlalchemy/engine/base.py
lib/sqlalchemy/engine/ddl.py
lib/sqlalchemy/schema.py
lib/sqlalchemy/sql/visitors.py
test/engine/test_bind.py
test/engine/test_ddlevents.py

diff --git a/CHANGES b/CHANGES
index e997eb56c87baf1d6caf068c80d030cdb8557eaa..c11fa3431d4c28d709a88e2155bd71613ec66bc1 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -121,6 +121,9 @@ CHANGES
     to get_primary_keys() except returns a dict that includes the
     name of the constraint, for supported backends (PG so far).
     [ticket:1769]
+
+  - Table.create() and Table.drop() no longer apply metadata-
+    level create/drop events.  [ticket:1771]
     
 - ext
   - the compiler extension now allows @compiles decorators
index d3579606306bad2204db7e6590da9a504a1899ee..5068167c3ae890364f3d44a169e1ece42ed6ffd4 100644 (file)
@@ -1497,14 +1497,14 @@ class Engine(Connectable, log.Identified):
         self.pool = self.pool.recreate()
 
     def create(self, entity, connection=None, **kwargs):
-        """Create a table or index within this engine's database connection given a schema.Table object."""
+        """Create a table or index within this engine's database connection given a schema object."""
 
         from sqlalchemy.engine import ddl
 
         self._run_visitor(ddl.SchemaGenerator, entity, connection=connection, **kwargs)
 
     def drop(self, entity, connection=None, **kwargs):
-        """Drop a table or index within this engine's database connection given a schema.Table object."""
+        """Drop a table or index within this engine's database connection given a schema object."""
 
         from sqlalchemy.engine import ddl
 
index ef10aa5ea74fdcd64aa0e1ab06d618ba8376b3dc..74205dbb03cda165ffd9e71df8ccd3c0979379ca 100644 (file)
@@ -39,12 +39,15 @@ class SchemaGenerator(DDLBase):
             listener('before-create', metadata, self.connection, tables=collection)
             
         for table in collection:
-            self.traverse_single(table)
+            self.traverse_single(table, create_ok=True)
 
         for listener in metadata.ddl_listeners['after-create']:
             listener('after-create', metadata, self.connection, tables=collection)
 
-    def visit_table(self, table):
+    def visit_table(self, table, create_ok=False):
+        if not create_ok and not self._can_create(table):
+            return
+            
         for listener in table.ddl_listeners['before-create']:
             listener('before-create', table, self.connection)
 
@@ -92,7 +95,7 @@ class SchemaDropper(DDLBase):
             listener('before-drop', metadata, self.connection, tables=collection)
         
         for table in collection:
-            self.traverse_single(table)
+            self.traverse_single(table, drop_ok=True)
 
         for listener in metadata.ddl_listeners['after-drop']:
             listener('after-drop', metadata, self.connection, tables=collection)
@@ -106,7 +109,10 @@ class SchemaDropper(DDLBase):
     def visit_index(self, index):
         self.connection.execute(schema.DropIndex(index))
 
-    def visit_table(self, table):
+    def visit_table(self, table, drop_ok=False):
+        if not drop_ok and not self._can_drop(table):
+            return
+            
         for listener in table.ddl_listeners['before-drop']:
             listener('before-drop', table, self.connection)
 
index 0e03be686f614e5b04d1665d96286abcd9cfd154..4e4468a850c0b1aea40b6c130315e11b5822d802 100644 (file)
@@ -405,15 +405,23 @@ class Table(SchemaItem, expression.TableClause):
         """Issue a ``CREATE`` statement for this table.
 
         See also ``metadata.create_all()``.
+
         """
-        self.metadata.create_all(bind=bind, checkfirst=checkfirst, tables=[self])
+
+        if bind is None:
+            bind = _bind_or_error(self)
+        bind.create(self, checkfirst=checkfirst)
 
     def drop(self, bind=None, checkfirst=False):
         """Issue a ``DROP`` statement for this table.
 
         See also ``metadata.drop_all()``.
+
         """
-        self.metadata.drop_all(bind=bind, checkfirst=checkfirst, tables=[self])
+        if bind is None:
+            bind = _bind_or_error(self)
+        bind.drop(self, checkfirst=checkfirst)
+        
 
     def tometadata(self, metadata, schema=RETAIN_SCHEMA):
         """Return a copy of this ``Table`` associated with a different ``MetaData``."""
index 799486c02f7346059ab419c540d4fe8d2edc0be9..791e3b80c492e3b5dbf4c358c37f54f678ba5caf 100644 (file)
@@ -70,11 +70,11 @@ class ClauseVisitor(object):
     
     __traverse_options__ = {}
     
-    def traverse_single(self, obj):
+    def traverse_single(self, obj, **kw):
         for v in self._visitor_iterator:
             meth = getattr(v, "visit_%s" % obj.__visit_name__, None)
             if meth:
-                return meth(obj)
+                return meth(obj, **kw)
     
     def iterate(self, obj):
         """traverse the given expression structure, returning an iterator of all elements."""
index 1122f1632fbdb4cb4f8a4724b29a38f10c3dff8b..c958f6f4c5baaface2d15abfd6e5e984ae0be1ad 100644 (file)
@@ -31,16 +31,14 @@ class BindTest(testing.TestBase):
                 table.drop(*args[0], **args[1])
                 assert not table.exists(*args[0], **args[1])
 
-    def test_create_drop_err(self):
+    def test_create_drop_err_metadata(self):
         metadata = MetaData()
         table = Table('test_table', metadata,
             Column('foo', Integer))
-
+        
         for meth in [
             metadata.create_all,
             metadata.drop_all,
-            table.create,
-            table.drop,
         ]:
             try:
                 meth()
@@ -54,27 +52,7 @@ class BindTest(testing.TestBase):
                     "against.  Either execute with an explicit connection or "
                     "assign the MetaData's .bind to enable implicit execution.")
 
-        for meth in [
-            table.exists,
-            # future:
-            #table.create,
-            #table.drop,
-        ]:
-            try:
-                meth()
-                assert False
-            except exc.UnboundExecutionError, e:
-                eq_(
-                    str(e),
-                    "The Table 'test_table' "
-                    "is not bound to an Engine or Connection.  "
-                    "Execution can not proceed without a database to execute "
-                    "against.  Either execute with an explicit connection or "
-                    "assign this Table's .metadata.bind to enable implicit "
-                    "execution.")
-
-    @testing.future
-    def test_create_drop_err2(self):
+    def test_create_drop_err_table(self):
         metadata = MetaData()
         table = Table('test_table', metadata,
             Column('foo', Integer))
index 2e5817c0129208b5f1d1d3075e8a0a918e95fd2b..06d2935262533d05e8754554a851e933e4583f85 100644 (file)
@@ -156,7 +156,6 @@ class DDLEventTest(TestBase):
         metadata.drop_all(bind)
         assert canary.state == 'after-create'
 
-    @testing.future
     def test_metadata_table_isolation(self):
         metadata, table, bind = self.metadata, self.table, self.bind
 
@@ -166,8 +165,6 @@ class DDLEventTest(TestBase):
         metadata_canary = self.Canary(metadata, bind)
         metadata.ddl_listeners['before-create'].append(metadata_canary.before_create)
 
-        # currently, table.create() routes through the same execution
-        # path that metadata.create_all() does
         self.table.create(self.bind)
         assert metadata_canary.state == None