diff --git a/sqlalchemy_utils/listeners.py b/sqlalchemy_utils/listeners.py index f2428cd..8213272 100644 --- a/sqlalchemy_utils/listeners.py +++ b/sqlalchemy_utils/listeners.py @@ -235,6 +235,8 @@ def auto_delete_orphans(attr): 'The relationship argument given for auto_delete_orphans needs to ' 'have a backref relationship set.' ) + if isinstance(backref, tuple): + backref = backref[0] @sa.event.listens_for(sa.orm.Session, 'after_flush') def delete_orphan_listener(session, ctx): @@ -257,7 +259,7 @@ def auto_delete_orphans(attr): ( session.query(target_class) .filter( - ~getattr(target_class, attr.property.backref).any() + ~getattr(target_class, backref).any() ) .delete(synchronize_session=False) ) diff --git a/tests/test_auto_delete_orphans.py b/tests/test_auto_delete_orphans.py index 06daaa1..fc7fd8d 100644 --- a/tests/test_auto_delete_orphans.py +++ b/tests/test_auto_delete_orphans.py @@ -1,5 +1,6 @@ import pytest import sqlalchemy as sa +from sqlalchemy.orm import backref from sqlalchemy_utils import auto_delete_orphans, ImproperlyConfigured @@ -36,17 +37,18 @@ def Tag(Base): return Tag -@pytest.fixture -def Entry(Base, Tag, tagging_tbl): +@pytest.fixture(params=['entries', backref('entries', lazy='select')], + ids=['backref_string', 'backref_with_keywords']) +def Entry(Base, Tag, tagging_tbl, request): class Entry(Base): __tablename__ = 'entry' id = sa.Column(sa.Integer, primary_key=True) tags = sa.orm.relationship( - 'Tag', + Tag, secondary=tagging_tbl, - backref='entries' + backref=request.param ) auto_delete_orphans(Entry.tags) return Entry @@ -60,7 +62,7 @@ def EntryWithoutTagsBackref(Base, Tag, tagging_tbl): id = sa.Column(sa.Integer, primary_key=True) tags = sa.orm.relationship( - 'Tag', + Tag, secondary=tagging_tbl ) return EntryWithoutTagsBackref