summaryrefslogtreecommitdiff
path: root/test/ext/declarative/test_basic.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2018-07-09 18:24:12 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2018-07-09 18:24:12 -0400
commitf34f634824da18a71f3c898a2e19e19e5f26bede (patch)
tree43c07ea44f5e05c2b17f139258c9cd135ff4a38d /test/ext/declarative/test_basic.py
parent941143858ba949c3a4a2dfcc5cd710ae6d4146e1 (diff)
downloadsqlalchemy-f34f634824da18a71f3c898a2e19e19e5f26bede.tar.gz
Expire memoizations on setattr/delattr, check in delattr
Fixed bug where declarative would not update the state of the :class:`.Mapper` as far as what attributes were present, when additional attributes were added or removed after the mapper attribute collections had already been called and memoized. Addtionally, a ``NotImplementedError`` is now raised if a fully mapped attribute (e.g. column, relationship, etc.) is deleted from a class that is currently mapped, since the mapper will not function correctly if the attribute has been removed. Change-Id: Idaca8e0237b31aa1d6564d94c3a179d7dc6b5df9 Fixes: #4133
Diffstat (limited to 'test/ext/declarative/test_basic.py')
-rw-r--r--test/ext/declarative/test_basic.py65
1 files changed, 64 insertions, 1 deletions
diff --git a/test/ext/declarative/test_basic.py b/test/ext/declarative/test_basic.py
index 5d1655e87..d2dc1a425 100644
--- a/test/ext/declarative/test_basic.py
+++ b/test/ext/declarative/test_basic.py
@@ -2,6 +2,7 @@
from sqlalchemy.testing import eq_, assert_raises, \
assert_raises_message, expect_warnings, is_
from sqlalchemy.ext import declarative as decl
+from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy import exc
import sqlalchemy as sa
from sqlalchemy import testing, util
@@ -1768,7 +1769,7 @@ class DeclarativeTest(DeclarativeTestBase):
class Test(Base):
__tablename__ = 'test'
id = Column(Integer, primary_key=True)
- # MARKMARK
+
eq_(
canary.mock_calls,
[
@@ -1786,6 +1787,68 @@ class DeclarativeTest(DeclarativeTestBase):
eq_(Base.__doc__, MyBase.__doc__)
+ def test_delattr_mapped_raises(self):
+ Base = decl.declarative_base()
+
+ class Foo(Base):
+ __tablename__ = 'foo'
+
+ id = Column(Integer, primary_key=True)
+ data = Column(String)
+
+ def go():
+ del Foo.data
+
+ assert_raises_message(
+ NotImplementedError,
+ "Can't un-map individual mapped attributes on a mapped class.",
+ go
+ )
+
+ def test_delattr_hybrid_fine(self):
+ Base = decl.declarative_base()
+
+ class Foo(Base):
+ __tablename__ = 'foo'
+
+ id = Column(Integer, primary_key=True)
+ data = Column(String)
+
+ @hybrid_property
+ def data_hybrid(self):
+ return self.data
+
+ assert "data_hybrid" in Foo.__mapper__.all_orm_descriptors.keys()
+
+ del Foo.data_hybrid
+
+ assert "data_hybrid" not in Foo.__mapper__.all_orm_descriptors.keys()
+
+ assert not hasattr(Foo, "data_hybrid")
+
+ def test_setattr_hybrid_updates_descriptors(self):
+ Base = decl.declarative_base()
+
+ class Foo(Base):
+ __tablename__ = 'foo'
+
+ id = Column(Integer, primary_key=True)
+ data = Column(String)
+
+ assert "data_hybrid" not in Foo.__mapper__.all_orm_descriptors.keys()
+
+ @hybrid_property
+ def data_hybrid(self):
+ return self.data
+ Foo.data_hybrid = data_hybrid
+ assert "data_hybrid" in Foo.__mapper__.all_orm_descriptors.keys()
+
+ del Foo.data_hybrid
+
+ assert "data_hybrid" not in Foo.__mapper__.all_orm_descriptors.keys()
+
+ assert not hasattr(Foo, "data_hybrid")
+
def _produce_test(inline, stringbased):