Add get_tables utility function
This commit is contained in:
@@ -8,6 +8,7 @@ Here you can see the full list of changes between each SQLAlchemy-Utils release.
|
|||||||
^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
- Added get_referencing_foreign_keys
|
- Added get_referencing_foreign_keys
|
||||||
|
- Added get_tables
|
||||||
|
|
||||||
|
|
||||||
0.25.4 (2014-04-22)
|
0.25.4 (2014-04-22)
|
||||||
|
@@ -34,6 +34,12 @@ get_referencing_foreign_keys
|
|||||||
.. autofunction:: get_referencing_foreign_keys
|
.. autofunction:: get_referencing_foreign_keys
|
||||||
|
|
||||||
|
|
||||||
|
get_tables
|
||||||
|
^^^^^^^^^^
|
||||||
|
|
||||||
|
.. autofunction:: get_tables
|
||||||
|
|
||||||
|
|
||||||
query_entities
|
query_entities
|
||||||
^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
@@ -14,6 +14,7 @@ from .functions import (
|
|||||||
get_declarative_base,
|
get_declarative_base,
|
||||||
get_primary_keys,
|
get_primary_keys,
|
||||||
get_referencing_foreign_keys,
|
get_referencing_foreign_keys,
|
||||||
|
get_tables,
|
||||||
identity,
|
identity,
|
||||||
mock_engine,
|
mock_engine,
|
||||||
naturally_equivalent,
|
naturally_equivalent,
|
||||||
@@ -82,6 +83,7 @@ __all__ = (
|
|||||||
get_declarative_base,
|
get_declarative_base,
|
||||||
get_primary_keys,
|
get_primary_keys,
|
||||||
get_referencing_foreign_keys,
|
get_referencing_foreign_keys,
|
||||||
|
get_tables,
|
||||||
identity,
|
identity,
|
||||||
instrumented_list,
|
instrumented_list,
|
||||||
merge,
|
merge,
|
||||||
|
@@ -16,6 +16,7 @@ from .orm import (
|
|||||||
get_declarative_base,
|
get_declarative_base,
|
||||||
get_primary_keys,
|
get_primary_keys,
|
||||||
get_referencing_foreign_keys,
|
get_referencing_foreign_keys,
|
||||||
|
get_tables,
|
||||||
getdotattr,
|
getdotattr,
|
||||||
has_changes,
|
has_changes,
|
||||||
identity,
|
identity,
|
||||||
@@ -35,6 +36,7 @@ __all__ = (
|
|||||||
'get_declarative_base',
|
'get_declarative_base',
|
||||||
'get_primary_keys',
|
'get_primary_keys',
|
||||||
'get_referencing_foreign_keys',
|
'get_referencing_foreign_keys',
|
||||||
|
'get_tables',
|
||||||
'getdotattr',
|
'getdotattr',
|
||||||
'has_changes',
|
'has_changes',
|
||||||
'identity',
|
'identity',
|
||||||
|
@@ -31,17 +31,17 @@ def get_referencing_foreign_keys(mixed):
|
|||||||
if isinstance(mixed, sa.Table):
|
if isinstance(mixed, sa.Table):
|
||||||
tables = [mixed]
|
tables = [mixed]
|
||||||
else:
|
else:
|
||||||
# TODO: make this support joined table inheritance
|
tables = get_tables(mixed)
|
||||||
tables = [mixed.__table__]
|
|
||||||
|
|
||||||
referencing_foreign_keys = set()
|
referencing_foreign_keys = set()
|
||||||
|
|
||||||
for table in mixed.metadata.tables.values():
|
for table in mixed.metadata.tables.values():
|
||||||
for constraint in table.constraints:
|
if table not in tables:
|
||||||
if isinstance(constraint, sa.sql.schema.ForeignKeyConstraint):
|
for constraint in table.constraints:
|
||||||
for fk in constraint.elements:
|
if isinstance(constraint, sa.sql.schema.ForeignKeyConstraint):
|
||||||
if any(fk.references(t) for t in tables):
|
for fk in constraint.elements:
|
||||||
referencing_foreign_keys.add(fk)
|
if any(fk.references(t) for t in tables):
|
||||||
|
referencing_foreign_keys.add(fk)
|
||||||
return referencing_foreign_keys
|
return referencing_foreign_keys
|
||||||
|
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ def get_primary_keys(mixed):
|
|||||||
|
|
||||||
get_primary_keys(sa.orm.aliased(User))
|
get_primary_keys(sa.orm.aliased(User))
|
||||||
|
|
||||||
get_primary_keys(sa.orm.alised(User.__table__))
|
get_primary_keys(sa.orm.aliased(User.__table__))
|
||||||
|
|
||||||
|
|
||||||
.. versionchanged: 0.25.3
|
.. versionchanged: 0.25.3
|
||||||
@@ -84,6 +84,37 @@ def get_primary_keys(mixed):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_tables(mixed):
|
||||||
|
"""
|
||||||
|
Return a list of tables associated with given SQLAlchemy object.
|
||||||
|
|
||||||
|
Let's say we have three classes which use joined table inheritance
|
||||||
|
TextItem, Article and BlogPost. Article and BlogPost inherit TextItem.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
get_tables(Article) # [Table('article', ...), Table('text_item')]
|
||||||
|
|
||||||
|
get_tables(Article())
|
||||||
|
|
||||||
|
get_tables(Article.__mapper__)
|
||||||
|
|
||||||
|
|
||||||
|
.. versionadded: 0.25.5
|
||||||
|
|
||||||
|
:param mixed:
|
||||||
|
SQLAlchemy Mapper / Declarative class or a SA Alias object wrapping
|
||||||
|
any of these objects.
|
||||||
|
"""
|
||||||
|
if isinstance(mixed, sa.orm.util.AliasedClass):
|
||||||
|
mapper = sa.inspect(mixed).mapper
|
||||||
|
else:
|
||||||
|
if not isclass(mixed):
|
||||||
|
mixed = mixed.__class__
|
||||||
|
mapper = sa.inspect(mixed)
|
||||||
|
return mapper.tables
|
||||||
|
|
||||||
|
|
||||||
def get_columns(mixed):
|
def get_columns(mixed):
|
||||||
"""
|
"""
|
||||||
Return a collection of all Column objects for given SQLAlchemy
|
Return a collection of all Column objects for given SQLAlchemy
|
||||||
|
@@ -32,3 +32,54 @@ class TestGetReferencingFksWithCompositeKeys(TestCase):
|
|||||||
def test_with_table(self):
|
def test_with_table(self):
|
||||||
fks = get_referencing_foreign_keys(self.User.__table__)
|
fks = get_referencing_foreign_keys(self.User.__table__)
|
||||||
assert self.Article.__table__.foreign_keys == fks
|
assert self.Article.__table__.foreign_keys == fks
|
||||||
|
|
||||||
|
|
||||||
|
class TestGetReferencingFksWithInheritance(TestCase):
|
||||||
|
def create_models(self):
|
||||||
|
class User(self.Base):
|
||||||
|
__tablename__ = 'user'
|
||||||
|
id = sa.Column(sa.Integer, primary_key=True)
|
||||||
|
type = sa.Column(sa.Unicode)
|
||||||
|
first_name = sa.Column(sa.Unicode(255), primary_key=True)
|
||||||
|
last_name = sa.Column(sa.Unicode(255), primary_key=True)
|
||||||
|
|
||||||
|
__mapper_args__ = {
|
||||||
|
'polymorphic_on': 'type'
|
||||||
|
}
|
||||||
|
|
||||||
|
class Admin(User):
|
||||||
|
__tablename__ = 'admin'
|
||||||
|
id = sa.Column(
|
||||||
|
sa.Integer, sa.ForeignKey(User.id), primary_key=True
|
||||||
|
)
|
||||||
|
|
||||||
|
class TextItem(self.Base):
|
||||||
|
__tablename__ = 'textitem'
|
||||||
|
id = sa.Column(sa.Integer, primary_key=True)
|
||||||
|
type = sa.Column(sa.Unicode)
|
||||||
|
author_id = sa.Column(sa.Integer, sa.ForeignKey(User.id))
|
||||||
|
__mapper_args__ = {
|
||||||
|
'polymorphic_on': 'type'
|
||||||
|
}
|
||||||
|
|
||||||
|
class Article(TextItem):
|
||||||
|
__tablename__ = 'article'
|
||||||
|
id = sa.Column(
|
||||||
|
sa.Integer, sa.ForeignKey(TextItem.id), primary_key=True
|
||||||
|
)
|
||||||
|
__mapper_args__ = {
|
||||||
|
'polymorphic_identity': 'article'
|
||||||
|
}
|
||||||
|
|
||||||
|
self.Admin = Admin
|
||||||
|
self.User = User
|
||||||
|
self.Article = Article
|
||||||
|
self.TextItem = TextItem
|
||||||
|
|
||||||
|
def test_with_declarative_class(self):
|
||||||
|
fks = get_referencing_foreign_keys(self.Admin)
|
||||||
|
assert self.TextItem.__table__.foreign_keys == fks
|
||||||
|
|
||||||
|
def test_with_table(self):
|
||||||
|
fks = get_referencing_foreign_keys(self.Admin.__table__)
|
||||||
|
assert fks == set([])
|
||||||
|
Reference in New Issue
Block a user