Improve coverage and add more docs

This commit is contained in:
Konsta Vesterinen
2014-05-07 14:38:19 +03:00
parent 64a31b4478
commit 2193d27d7b
2 changed files with 53 additions and 9 deletions

View File

@@ -43,18 +43,28 @@ def dependencies(obj, foreign_keys=None):
The common use case is checking for all dependent objects before deleting
parent object and inform the user if there are dependent objects with
ondelete='RESTRICT' foreign keys. If this kind of checking is not used
it will lead to nasty IntegrityErrors being raised. This can be achieved
as follows::
it will lead to nasty IntegrityErrors being raised.
In the following example we delete given user if it doesn't have any
foreign key restricted dependencies.
::
from sqlalchemy_utils import get_referencing_foreign_keys
user = session.query(User).get(some_user_id)
deps = list(
dependencies(
user,
(
fk for fk in get_referencing_foreign_keys(obj)
fk for fk in get_referencing_foreign_keys(User)
# On most databases RESTRICT is the default mode hence we
# check for None values also
if fk.ondelete='RESTRICT' or fk.ondelete is None
if fk.ondelete == 'RESTRICT' or fk.ondelete is None
)
).limit(5)
)
@@ -62,6 +72,8 @@ def dependencies(obj, foreign_keys=None):
if deps:
# Do something to inform the user
pass
else:
session.delete(user)
:param obj: SQLAlchemy declarative model object
@@ -73,6 +85,8 @@ def dependencies(obj, foreign_keys=None):
.. note::
This function does not support exotic mappers that use multiple tables
.. seealso:: :func:`get_referencing_foreign_keys`
.. versionadded: 0.26.0
"""
if foreign_keys is None:
@@ -142,6 +156,7 @@ def get_referencing_foreign_keys(mixed):
# or textitem table.
get_referencing_foreign_keys(Article)
.. seealso:: :func:`get_tables`
"""
if isinstance(mixed, sa.Table):
tables = [mixed]

View File

@@ -1,5 +1,5 @@
import sqlalchemy as sa
from sqlalchemy_utils.functions.orm import dependencies
from sqlalchemy_utils import dependencies, get_referencing_foreign_keys
from tests import TestCase
@@ -15,7 +15,9 @@ class TestDependencies(TestCase):
__tablename__ = 'article'
id = sa.Column(sa.Integer, primary_key=True)
author_id = sa.Column(sa.Integer, sa.ForeignKey('user.id'))
owner_id = sa.Column(sa.Integer, sa.ForeignKey('user.id'))
owner_id = sa.Column(
sa.Integer, sa.ForeignKey('user.id', ondelete='SET NULL')
)
author = sa.orm.relationship(User, foreign_keys=[author_id])
owner = sa.orm.relationship(User, foreign_keys=[owner_id])
@@ -23,15 +25,17 @@ class TestDependencies(TestCase):
class BlogPost(self.Base):
__tablename__ = 'blog_post'
id = sa.Column(sa.Integer, primary_key=True)
author_id = sa.Column(sa.Integer, sa.ForeignKey('user.id'))
owner_id = sa.Column(
sa.Integer, sa.ForeignKey('user.id', ondelete='CASCADE')
)
author = sa.orm.relationship(User)
owner = sa.orm.relationship(User)
self.User = User
self.Article = Article
self.BlogPost = BlogPost
def test_multiple_refs(self):
def test_returns_all_dependent_objects(self):
user = self.User(first_name=u'John')
articles = [
self.Article(author=user),
@@ -48,6 +52,31 @@ class TestDependencies(TestCase):
assert articles[2] in deps
assert articles[3] in deps
def test_with_foreign_keys_parameter(self):
user = self.User(first_name=u'John')
objects = [
self.Article(author=user),
self.Article(),
self.Article(owner=user),
self.Article(author=user, owner=user),
self.BlogPost(owner=user)
]
self.session.add_all(objects)
self.session.commit()
deps = list(
dependencies(
user,
(
fk for fk in get_referencing_foreign_keys(self.User)
if fk.ondelete == 'RESTRICT' or fk.ondelete is None
)
).limit(5)
)
assert len(deps) == 2
assert objects[0] in deps
assert objects[3] in deps
class TestDependenciesWithCompositeKeys(TestCase):
def create_models(self):