From 7a2ebf9b4b1d93cc99f8b0a0a17db0c49437ee9d Mon Sep 17 00:00:00 2001 From: Indivar Mishra Date: Mon, 6 Feb 2023 18:27:40 +0530 Subject: [PATCH] fix(#25): handle attributes which are not accessible in ORM doing a check for property key before enabling active_history to make sure it can be directly accessed by parent_cls --- sqlalchemy_history/builder.py | 5 +- .../test_bug_25_polymorphic_on_attr.py | 46 +++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 tests/reported_bugs/test_bug_25_polymorphic_on_attr.py diff --git a/sqlalchemy_history/builder.py b/sqlalchemy_history/builder.py index 823f5646..40cc3958 100644 --- a/sqlalchemy_history/builder.py +++ b/sqlalchemy_history/builder.py @@ -174,7 +174,10 @@ def enable_active_history(self, version_classes): """ for cls in version_classes: for prop in sa.inspect(cls).iterate_properties: - getattr(cls, prop.key).impl.active_history = True + if hasattr(cls, prop.key): + # Mapper Arg `_sa_polymorphic_on` appear as columnproperty but is not attr of cls + # Giving AttrError + getattr(cls, prop.key).impl.active_history = True def create_column_aliases(self, version_classes): """ diff --git a/tests/reported_bugs/test_bug_25_polymorphic_on_attr.py b/tests/reported_bugs/test_bug_25_polymorphic_on_attr.py new file mode 100644 index 00000000..fc60e589 --- /dev/null +++ b/tests/reported_bugs/test_bug_25_polymorphic_on_attr.py @@ -0,0 +1,46 @@ +import datetime +import sqlalchemy as sa +from copy import copy +from tests import TestCase + + +class TestBug25(TestCase): + # ref: https://github.com/corridor/sqlalchemy-history/issues/25 + def create_models(self): + class Writer(self.Model): + __tablename__ = "writer" + __versioned__ = {} + + id = sa.Column(sa.Integer, sa.Sequence(f"{__tablename__}_seq"), primary_key=True) + name = sa.Column(sa.String(255)) + type = sa.Column(sa.String(255)) + + __mapper_args__ = { + "polymorphic_on": ( + sa.case( + [(type.in_(["poet", "lyricist"]), "bard")], + else_=type, + ) + ), + "polymorphic_identity": "writer", + } + + class Author(self.Model): + __tablename__ = "author" + __versioned__ = {} + id = sa.Column(sa.Integer, sa.Sequence(f"{__tablename__}_seq"), primary_key=True) + name = sa.Column(sa.String(255)) + + __mapper_args__ = { + "polymorphic_identity": "author", + } + + self.Writer = Writer + self.Author = Author + + def test_inserting_entries(self): + writer = self.Writer(name="Writer 1") + author = self.Author(name="Author 1") + self.session.add(writer) + self.session.add(author) + self.session.commit()