From: Mike Bayer Date: Thu, 13 May 2010 19:53:18 +0000 (-0400) Subject: - Added table.add_is_dependent_on(othertable), allows manual X-Git-Tag: rel_0_6_1~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=14d523265203d21152411b5f3c18843b09b23554;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - Added table.add_is_dependent_on(othertable), allows manual placement of dependency rules between two Table objects for use within create_all(), drop_all(), sorted_tables. [ticket:1801] --- diff --git a/CHANGES b/CHANGES index 61cec42d25..3a41e098c7 100644 --- a/CHANGES +++ b/CHANGES @@ -26,6 +26,11 @@ CHANGES is like `col.in_(text("select id from table"))`. [ticket:1793] + - Added table.add_is_dependent_on(othertable), allows manual + placement of dependency rules between two Table objects + for use within create_all(), drop_all(), sorted_tables. + [ticket:1801] + - Fixed bug that prevented implicit RETURNING from functioning properly with composite primary key that contained zeroes. [ticket:1778] diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py index 168296db61..a2d499f845 100644 --- a/lib/sqlalchemy/schema.py +++ b/lib/sqlalchemy/schema.py @@ -224,6 +224,7 @@ class Table(SchemaItem, expression.TableClause): self._columns = expression.ColumnCollection() self._set_primary_key(PrimaryKeyConstraint()) self._foreign_keys = util.OrderedSet() + self._extra_dependencies = set() self.ddl_listeners = util.defaultdict(list) self.kwargs = {} if self.schema is not None: @@ -338,6 +339,20 @@ class Table(SchemaItem, expression.TableClause): return self.metadata and self.metadata.bind or None + def add_is_dependent_on(self, table): + """Add a 'dependency' for this Table. + + This is another Table object which must be created + first before this one can, or dropped after this one. + + Usually, dependencies between tables are determined via + ForeignKey objects. However, for other situations that + create dependencies outside of foreign keys (rules, inheriting), + this method can manually establish such a link. + + """ + self._extra_dependencies.add(table) + def append_column(self, column): """Append a ``Column`` to this ``Table``.""" diff --git a/lib/sqlalchemy/sql/util.py b/lib/sqlalchemy/sql/util.py index e4ebe95384..14ea42d2c7 100644 --- a/lib/sqlalchemy/sql/util.py +++ b/lib/sqlalchemy/sql/util.py @@ -22,6 +22,11 @@ def sort_tables(tables): visitors.traverse(table, {'schema_visitor':True}, {'foreign_key':visit_foreign_key}) + + tuples.extend( + [parent, table] for parent in table._extra_dependencies + ) + return list(topological.sort(tuples, tables)) def find_join_source(clauses, join_to): diff --git a/test/engine/test_metadata.py b/test/engine/test_metadata.py index 41b744d9bb..25a9a6d140 100644 --- a/test/engine/test_metadata.py +++ b/test/engine/test_metadata.py @@ -250,6 +250,25 @@ class MetaDataTest(TestBase, ComparesTables): eq_(str(table_c.join(table2_c).onclause), str(table_c.c.myid == table2_c.c.myid)) eq_(str(table_c.join(table2_c).onclause), "myschema.mytable.myid = myschema.othertable.myid") + def test_manual_dependencies(self): + meta = MetaData() + a = Table('a', meta, Column('foo', Integer)) + b = Table('b', meta, Column('foo', Integer)) + c = Table('c', meta, Column('foo', Integer)) + d = Table('d', meta, Column('foo', Integer)) + e = Table('e', meta, Column('foo', Integer)) + + e.add_is_dependent_on(c) + a.add_is_dependent_on(b) + b.add_is_dependent_on(d) + e.add_is_dependent_on(b) + c.add_is_dependent_on(a) + eq_( + meta.sorted_tables, + [d, b, a, c, e] + ) + + def test_tometadata_strip_schema(self): meta = MetaData()