fix: add db.util.make_topo_sortkey()
function
This commit is contained in:
parent
c3aa97ed27
commit
d95b101dbf
|
@ -27,6 +27,7 @@ Database Utilities
|
|||
import uuid as _uuid
|
||||
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy import orm
|
||||
from sqlalchemy.dialects.postgresql import UUID as PGUUID
|
||||
|
||||
from wuttjamaican.util import make_uuid
|
||||
|
@ -127,3 +128,26 @@ def uuid_fk_column(target_column, *args, **kwargs):
|
|||
if not args:
|
||||
args = (sa.String(length=32), sa.ForeignKey(target_column))
|
||||
return sa.Column(*args, **kwargs)
|
||||
|
||||
|
||||
def make_topo_sortkey(model):
|
||||
"""
|
||||
Returns a function suitable for use as a ``key`` kwarg to a
|
||||
standard Python sorting call. This key function will expect a
|
||||
single class mapper and return a sequence number associated with
|
||||
that model. The sequence is determined by SQLAlchemy's
|
||||
topological table sorting.
|
||||
|
||||
:param model: Usually the :term:`app model`, but can be any module
|
||||
containing model classes.
|
||||
"""
|
||||
metadata = model.Base.metadata
|
||||
tables = dict([(table.name, i)
|
||||
for i, table in enumerate(metadata.sorted_tables, 1)])
|
||||
|
||||
def sortkey(name):
|
||||
cls = getattr(model, name)
|
||||
mapper = orm.class_mapper(cls)
|
||||
return tuple(tables[t.name] for t in mapper.tables)
|
||||
|
||||
return sortkey
|
||||
|
|
|
@ -11,6 +11,7 @@ try:
|
|||
from wuttjamaican.db import util as mod
|
||||
from wuttjamaican.db.model.base import Setting
|
||||
from wuttjamaican.util import make_true_uuid
|
||||
from wuttjamaican.testing import DataTestCase
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
|
@ -124,3 +125,17 @@ else:
|
|||
self.assertIsInstance(column, sa.Column)
|
||||
self.assertIsInstance(column.type, sa.String)
|
||||
self.assertEqual(column.type.length, 32)
|
||||
|
||||
|
||||
class TestMakeTopoSortkey(DataTestCase):
|
||||
|
||||
def test_basic(self):
|
||||
model = self.app.model
|
||||
sortkey = mod.make_topo_sortkey(model)
|
||||
original = ['User', 'Person', 'UserRole', 'Role']
|
||||
|
||||
# models are sorted so dependants come later
|
||||
result = sorted(original, key=sortkey)
|
||||
self.assertTrue(result.index('Role') < result.index('UserRole'))
|
||||
self.assertTrue(result.index('User') < result.index('UserRole'))
|
||||
self.assertTrue(result.index('Person') < result.index('User'))
|
||||
|
|
Loading…
Reference in a new issue