summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2008-08-19 21:27:34 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2008-08-19 21:27:34 +0000
commit427ed1966f0f9ce13df49dcdbe43ce48333e94fa (patch)
tree20c34c3a838c37c73828473ea47e889c51f1fe8f
parent20c82967ca98ceead88401ca8f35f8cf0e758318 (diff)
downloadsqlalchemy-427ed1966f0f9ce13df49dcdbe43ce48333e94fa.tar.gz
- fixed a bug in declarative test which was looking for old version of history
- Added "sorted_tables" accessor to MetaData, which returns Table objects sorted in order of dependency as a list. This deprecates the MetaData.table_iterator() method. The "reverse=False" keyword argument has also been removed from util.sort_tables(); use the Python 'reversed' function to reverse the results. [ticket:1033]
-rw-r--r--CHANGES10
-rw-r--r--lib/sqlalchemy/orm/mapper.py2
-rw-r--r--lib/sqlalchemy/schema.py15
-rw-r--r--lib/sqlalchemy/sql/compiler.py14
-rw-r--r--lib/sqlalchemy/sql/util.py8
-rw-r--r--test/engine/_base.py4
-rw-r--r--test/engine/reflection.py4
-rw-r--r--test/ext/declarative.py4
-rw-r--r--test/orm/_base.py4
-rw-r--r--test/orm/_fixtures.py2
-rw-r--r--test/orm/inheritance/basic.py2
-rw-r--r--test/orm/inheritance/polymorph2.py2
-rw-r--r--test/testlib/testing.py2
13 files changed, 47 insertions, 26 deletions
diff --git a/CHANGES b/CHANGES
index 093a4b7fe..e5746ea3e 100644
--- a/CHANGES
+++ b/CHANGES
@@ -69,7 +69,15 @@ CHANGES
may now be a mix of lists and tuples. (Previously members
were always lists.)
-
+- schema
+ - Added "sorted_tables" accessor to MetaData, which returns
+ Table objects sorted in order of dependency as a list.
+ This deprecates the MetaData.table_iterator() method.
+ The "reverse=False" keyword argument has also been
+ removed from util.sort_tables(); use the Python
+ 'reversed' function to reverse the results.
+ [ticket:1033]
+
- sql
- Temporarily rolled back the "ORDER BY" enhancement from
[ticket:1068]. This feature is on hold pending further
diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py
index 3e5f418fa..d1713e6f9 100644
--- a/lib/sqlalchemy/orm/mapper.py
+++ b/lib/sqlalchemy/orm/mapper.py
@@ -1314,7 +1314,7 @@ class Mapper(object):
for t in mapper.tables:
table_to_mapper[t] = mapper
- for table in sqlutil.sort_tables(table_to_mapper.keys(), reverse=True):
+ for table in reversed(sqlutil.sort_tables(table_to_mapper.keys())):
delete = {}
for state, mapper, connection in tups:
if table not in mapper._pks_by_table:
diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py
index f6e55581f..bb97943eb 100644
--- a/lib/sqlalchemy/schema.py
+++ b/lib/sqlalchemy/schema.py
@@ -1534,14 +1534,23 @@ class MetaData(SchemaItem):
# TODO: scan all other tables and remove FK _column
del self.tables[table.key]
+ @util.deprecated('Deprecated. Use ``metadata.sorted_tables``')
def table_iterator(self, reverse=True, tables=None):
from sqlalchemy.sql.util import sort_tables
if tables is None:
tables = self.tables.values()
else:
tables = set(tables).intersection(self.tables.values())
- return iter(sort_tables(tables, reverse=reverse))
-
+ ret = sort_tables(tables)
+ if reverse:
+ ret = reversed(ret)
+ return iter(ret)
+
+ @property
+ def sorted_tables(self):
+ from sqlalchemy.sql.util import sort_tables
+ return sort_tables(self.tables.values())
+
def reflect(self, bind=None, schema=None, only=None):
"""Load all available table definitions from the database.
@@ -1660,8 +1669,8 @@ class MetaData(SchemaItem):
checkfirst
Defaults to True, don't issue CREATEs for tables already present
in the target database.
+
"""
-
if bind is None:
bind = _bind_or_error(self)
for listener in self.ddl_listeners['before-create']:
diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py
index 4a47df941..eacbe59e1 100644
--- a/lib/sqlalchemy/sql/compiler.py
+++ b/lib/sqlalchemy/sql/compiler.py
@@ -20,7 +20,7 @@ is otherwise internal to SQLAlchemy.
import string, re
from sqlalchemy import schema, engine, util, exc
-from sqlalchemy.sql import operators, functions
+from sqlalchemy.sql import operators, functions, util as sql_util
from sqlalchemy.sql import expression as sql
RESERVED_WORDS = set([
@@ -787,7 +787,11 @@ class SchemaGenerator(DDLBase):
return not self.checkfirst or not self.dialect.has_table(self.connection, table.name, schema=table.schema)
def visit_metadata(self, metadata):
- collection = [t for t in metadata.table_iterator(reverse=False, tables=self.tables) if self._can_create(t)]
+ if self.tables:
+ tables = self.tables
+ else:
+ tables = metadata.tables.values()
+ collection = [t for t in sql_util.sort_tables(tables) if self._can_create(t)]
for table in collection:
self.traverse_single(table)
if self.dialect.supports_alter:
@@ -950,7 +954,11 @@ class SchemaDropper(DDLBase):
self.dialect = dialect
def visit_metadata(self, metadata):
- collection = [t for t in metadata.table_iterator(reverse=True, tables=self.tables) if self._can_drop(t)]
+ if self.tables:
+ tables = self.tables
+ else:
+ tables = metadata.tables.values()
+ collection = [t for t in reversed(sql_util.sort_tables(tables)) if self._can_drop(t)]
if self.dialect.supports_alter:
for alterable in self.find_alterables(collection):
self.drop_foreignkey(alterable)
diff --git a/lib/sqlalchemy/sql/util.py b/lib/sqlalchemy/sql/util.py
index ba6b5a605..e1636ccf9 100644
--- a/lib/sqlalchemy/sql/util.py
+++ b/lib/sqlalchemy/sql/util.py
@@ -4,7 +4,7 @@ from itertools import chain
"""Utility functions that build upon SQL and Schema constructs."""
-def sort_tables(tables, reverse=False):
+def sort_tables(tables):
"""sort a collection of Table objects in order of their foreign-key dependency."""
tuples = []
@@ -18,11 +18,7 @@ def sort_tables(tables, reverse=False):
for table in tables:
visitors.traverse(table, {'schema_visitor':True}, {'foreign_key':visit_foreign_key})
- sequence = topological.sort(tuples, tables)
- if reverse:
- return reversed(sequence)
- else:
- return sequence
+ return topological.sort(tuples, tables)
def search(clause, target):
if not clause:
diff --git a/test/engine/_base.py b/test/engine/_base.py
index c215b2e96..3c31d378a 100644
--- a/test/engine/_base.py
+++ b/test/engine/_base.py
@@ -82,7 +82,7 @@ class TablesTest(testing.TestBase):
def tearDown(self):
# no need to run deletes if tables are recreated on setup
if self.run_define_tables != 'each' and self.run_deletes:
- for table in self.metadata.table_iterator(reverse=True):
+ for table in reversed(self.metadata.sorted_tables):
try:
table.delete().execute().close()
except sa.exc.DBAPIError, ex:
@@ -135,7 +135,7 @@ class TablesTest(testing.TestBase):
table = self.tables[table]
headers[table] = data[0]
rows[table] = data[1:]
- for table in self.metadata.table_iterator(reverse=False):
+ for table in self.metadata.sorted_tables:
if table not in headers:
continue
table.bind.execute(
diff --git a/test/engine/reflection.py b/test/engine/reflection.py
index 873c05aa5..5916e8cad 100644
--- a/test/engine/reflection.py
+++ b/test/engine/reflection.py
@@ -555,7 +555,7 @@ class CreateDropTest(TestBase):
)
def test_sorter( self ):
- tables = metadata.table_iterator(reverse=False)
+ tables = metadata.sorted_tables
table_names = [t.name for t in tables]
self.assert_( table_names == ['users', 'orders', 'items', 'email_addresses'] or table_names == ['users', 'email_addresses', 'orders', 'items'])
@@ -657,7 +657,7 @@ class SchemaTest(TestBase):
Column('col2', sa.Integer, sa.ForeignKey('someschema.table1.col1')),
schema='someschema')
# ensure this doesnt crash
- print [t for t in metadata.table_iterator()]
+ print [t for t in metadata.sorted_tables]
buf = StringIO.StringIO()
def foo(s, p=None):
buf.write(s)
diff --git a/test/ext/declarative.py b/test/ext/declarative.py
index c1a56ced2..b9fa57cf0 100644
--- a/test/ext/declarative.py
+++ b/test/ext/declarative.py
@@ -392,7 +392,7 @@ class DeclarativeTest(testing.TestBase, testing.AssertsExecutionResults):
u1 = User(name='u1', a='a', b='b')
eq_(u1.a, 'a')
- eq_(User.a.get_history(u1), (['a'], [], []))
+ eq_(User.a.get_history(u1), (['a'], (), ()))
sess = create_session()
sess.save(u1)
sess.flush()
@@ -777,7 +777,7 @@ class DeclarativeReflectionTest(testing.TestBase):
Base = decl.declarative_base(testing.db)
def tearDown(self):
- for t in reflection_metadata.table_iterator():
+ for t in reflection_metadata.sorted_tables:
t.delete().execute()
def tearDownAll(self):
diff --git a/test/orm/_base.py b/test/orm/_base.py
index 4523a3223..ae8cbd746 100644
--- a/test/orm/_base.py
+++ b/test/orm/_base.py
@@ -202,7 +202,7 @@ class MappedTest(ORMTest):
# no need to run deletes if tables are recreated on setup
if self.run_define_tables != 'each' and self.run_deletes:
- for table in self.metadata.table_iterator(reverse=True):
+ for table in reversed(self.metadata.sorted_tables):
try:
table.delete().execute().close()
except sa.exc.DBAPIError, ex:
@@ -264,7 +264,7 @@ class MappedTest(ORMTest):
table = self.tables[table]
headers[table] = data[0]
rows[table] = data[1:]
- for table in self.metadata.table_iterator(reverse=False):
+ for table in self.metadata.sorted_tables:
if table not in headers:
continue
table.bind.execute(
diff --git a/test/orm/_fixtures.py b/test/orm/_fixtures.py
index 77dd510b2..efab37487 100644
--- a/test/orm/_fixtures.py
+++ b/test/orm/_fixtures.py
@@ -153,7 +153,7 @@ item_keywords = fixture_table(
def _load_fixtures():
- for table in fixture_metadata.table_iterator(reverse=False):
+ for table in fixture_metadata.sorted_tables:
table.info[('fixture', 'loader')]()
def run_inserts_for(table, bind=None):
diff --git a/test/orm/inheritance/basic.py b/test/orm/inheritance/basic.py
index e3e374eed..b7759aaeb 100644
--- a/test/orm/inheritance/basic.py
+++ b/test/orm/inheritance/basic.py
@@ -653,7 +653,7 @@ class SyncCompileTest(ORMTest):
for j1 in (None, _b_table.c.a_id==_a_table.c.id, _a_table.c.id==_b_table.c.a_id):
for j2 in (None, _b_table.c.a_id==_c_table.c.b_a_id, _c_table.c.b_a_id==_b_table.c.a_id):
self._do_test(j1, j2)
- for t in _a_table.metadata.table_iterator(reverse=True):
+ for t in reversed(_a_table.metadata.sorted_tables):
t.delete().execute().close()
def _do_test(self, j1, j2):
diff --git a/test/orm/inheritance/polymorph2.py b/test/orm/inheritance/polymorph2.py
index 955a6b4e9..6e9cf305e 100644
--- a/test/orm/inheritance/polymorph2.py
+++ b/test/orm/inheritance/polymorph2.py
@@ -652,7 +652,7 @@ class GenerativeTest(TestBase, AssertsExecutionResults):
metadata.drop_all()
def tearDown(self):
clear_mappers()
- for t in metadata.table_iterator(reverse=True):
+ for t in reversed(metadata.sorted_tables):
t.delete().execute()
def testjointo(self):
diff --git a/test/testlib/testing.py b/test/testlib/testing.py
index 1c3b0f0bc..cc7736937 100644
--- a/test/testlib/testing.py
+++ b/test/testlib/testing.py
@@ -911,7 +911,7 @@ class ORMTest(TestBase, AssertsExecutionResults):
if not self.keep_mappers:
clear_mappers()
if not self.keep_data:
- for t in _otest_metadata.table_iterator(reverse=True):
+ for t in reversed(_otest_metadata.sorted_tables):
try:
t.delete().execute().close()
except Exception, e: