diff options
| author | mike bayer <mike_mp@zzzcomputing.com> | 2019-01-31 16:09:41 +0000 |
|---|---|---|
| committer | Gerrit Code Review <gerrit@bbpush.zzzcomputing.com> | 2019-01-31 16:09:41 +0000 |
| commit | 7e48d8b2a70b399ffa6ec874f824d6cee82980a0 (patch) | |
| tree | 54d6986ee5c2a56f8d9f374248f5a59301ebadb5 /test | |
| parent | 06d952950975f71d86a43bbc4f2cbd9edccbc7ee (diff) | |
| parent | 147f6d382c3b6f06c8efa5a24c07c9849473e7af (diff) | |
| download | sqlalchemy-7e48d8b2a70b399ffa6ec874f824d6cee82980a0.tar.gz | |
Merge "Add informative failure modes to _DeferredMapperConfig"
Diffstat (limited to 'test')
| -rw-r--r-- | test/ext/declarative/test_basic.py | 33 | ||||
| -rw-r--r-- | test/ext/declarative/test_inheritance.py | 63 | ||||
| -rw-r--r-- | test/ext/declarative/test_reflection.py | 22 | ||||
| -rw-r--r-- | test/ext/test_automap.py | 20 |
4 files changed, 136 insertions, 2 deletions
diff --git a/test/ext/declarative/test_basic.py b/test/ext/declarative/test_basic.py index 8b60a1176..3fe2f1bfe 100644 --- a/test/ext/declarative/test_basic.py +++ b/test/ext/declarative/test_basic.py @@ -15,6 +15,7 @@ from sqlalchemy import util from sqlalchemy.ext import declarative as decl from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.declarative import synonym_for +from sqlalchemy.ext.declarative.base import _DeferredMapperConfig from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy.orm import backref from sqlalchemy.orm import class_mapper @@ -25,6 +26,7 @@ from sqlalchemy.orm import composite from sqlalchemy.orm import configure_mappers from sqlalchemy.orm import create_session from sqlalchemy.orm import deferred +from sqlalchemy.orm import exc as orm_exc from sqlalchemy.orm import joinedload from sqlalchemy.orm import mapper from sqlalchemy.orm import properties @@ -116,6 +118,37 @@ class DeclarativeTest(DeclarativeTestBase): eq_(a1, Address(email="two")) eq_(a1.user, User(name="u1")) + def test_deferred_reflection_default_error(self): + class MyExt(object): + @classmethod + def prepare(cls): + "sample prepare method" + to_map = _DeferredMapperConfig.classes_for_base(cls) + for thingy in to_map: + thingy.map() + + @classmethod + def _sa_decl_prepare(cls): + pass + + class User(MyExt, Base): + __tablename__ = "user" + id = Column(Integer, primary_key=True) + + assert_raises_message( + orm_exc.UnmappedClassError, + "Class test.ext.declarative.test_basic.User has a deferred " + "mapping on it. It is not yet usable as a mapped class.", + Session().query, + User, + ) + + User.prepare() + + self.assert_compile( + Session().query(User), 'SELECT "user".id AS user_id FROM "user"' + ) + def test_unicode_string_resolve(self): class User(Base, fixtures.ComparableEntity): __tablename__ = "users" diff --git a/test/ext/declarative/test_inheritance.py b/test/ext/declarative/test_inheritance.py index 17b915da0..083fdb0db 100644 --- a/test/ext/declarative/test_inheritance.py +++ b/test/ext/declarative/test_inheritance.py @@ -14,6 +14,7 @@ from sqlalchemy.orm import close_all_sessions from sqlalchemy.orm import configure_mappers from sqlalchemy.orm import create_session from sqlalchemy.orm import deferred +from sqlalchemy.orm import exc as orm_exc from sqlalchemy.orm import mapper from sqlalchemy.orm import polymorphic_union from sqlalchemy.orm import relationship @@ -30,7 +31,6 @@ from sqlalchemy.testing.schema import Column from sqlalchemy.testing.schema import Table from test.orm.test_events import _RemoveListeners - Base = None @@ -1317,7 +1317,9 @@ class OverlapColPrecedenceTest(DeclarativeTestBase): self._run_test(Engineer, "eid", "pid") -class ConcreteInhTest(_RemoveListeners, DeclarativeTestBase): +class ConcreteInhTest( + _RemoveListeners, DeclarativeTestBase, testing.AssertsCompiledSQL +): def _roundtrip( self, Employee, @@ -1489,6 +1491,63 @@ class ConcreteInhTest(_RemoveListeners, DeclarativeTestBase): self._roundtrip(Employee, Manager, Engineer, Boss, polymorphic=False) + def test_abstract_concrete_base_didnt_configure(self): + class Employee(AbstractConcreteBase, Base, fixtures.ComparableEntity): + pass + + assert_raises_message( + orm_exc.UnmappedClassError, + "Class test.ext.declarative.test_inheritance.Employee is a " + "subclass of AbstractConcreteBase and has a mapping pending " + "until all subclasses are defined. Call the " + r"sqlalchemy.orm.configure_mappers\(\) function after all " + "subclasses have been defined to complete the " + "mapping of this class.", + Session().query, + Employee, + ) + + configure_mappers() + + # no subclasses yet. + assert_raises_message( + orm_exc.UnmappedClassError, + ".*and has a mapping pending", + Session().query, + Employee, + ) + + class Manager(Employee): + __tablename__ = "manager" + employee_id = Column( + Integer, primary_key=True, test_needs_autoincrement=True + ) + name = Column(String(50)) + golf_swing = Column(String(40)) + __mapper_args__ = { + "polymorphic_identity": "manager", + "concrete": True, + } + + # didnt call configure_mappers() again + assert_raises_message( + orm_exc.UnmappedClassError, + ".*and has a mapping pending", + Session().query, + Employee, + ) + + configure_mappers() + + self.assert_compile( + Session().query(Employee), + "SELECT pjoin.employee_id AS pjoin_employee_id, " + "pjoin.name AS pjoin_name, pjoin.golf_swing AS pjoin_golf_swing, " + "pjoin.type AS pjoin_type FROM (SELECT manager.employee_id " + "AS employee_id, manager.name AS name, manager.golf_swing AS " + "golf_swing, 'manager' AS type FROM manager) AS pjoin", + ) + def test_abstract_concrete_extension(self): class Employee(AbstractConcreteBase, Base, fixtures.ComparableEntity): pass diff --git a/test/ext/declarative/test_reflection.py b/test/ext/declarative/test_reflection.py index df1f0580c..8517acf0b 100644 --- a/test/ext/declarative/test_reflection.py +++ b/test/ext/declarative/test_reflection.py @@ -6,9 +6,11 @@ from sqlalchemy.ext import declarative as decl from sqlalchemy.ext.declarative.base import _DeferredMapperConfig from sqlalchemy.orm import clear_mappers from sqlalchemy.orm import create_session +from sqlalchemy.orm import exc as orm_exc from sqlalchemy.orm import relationship from sqlalchemy.orm import Session from sqlalchemy.testing import assert_raises +from sqlalchemy.testing import assert_raises_message from sqlalchemy.testing import eq_ from sqlalchemy.testing import fixtures from sqlalchemy.testing.schema import Column @@ -254,6 +256,26 @@ class DeferredReflectionTest(DeferredReflectBase): eq_(a1, Address(email="two")) eq_(a1.user, User(name="u1")) + def test_exception_prepare_not_called(self): + class User(decl.DeferredReflection, fixtures.ComparableEntity, Base): + __tablename__ = "users" + addresses = relationship("Address", backref="user") + + class Address( + decl.DeferredReflection, fixtures.ComparableEntity, Base + ): + __tablename__ = "addresses" + + assert_raises_message( + orm_exc.UnmappedClassError, + "Class test.ext.declarative.test_reflection.User is a " + "subclass of DeferredReflection. Mappings are not produced " + r"until the .prepare\(\) method is called on the class " + "hierarchy.", + Session().query, + User, + ) + def test_basic_deferred(self): class User(decl.DeferredReflection, fixtures.ComparableEntity, Base): __tablename__ = "users" diff --git a/test/ext/test_automap.py b/test/ext/test_automap.py index e2dd5b11e..25c43f173 100644 --- a/test/ext/test_automap.py +++ b/test/ext/test_automap.py @@ -11,8 +11,11 @@ from sqlalchemy import testing from sqlalchemy.ext.automap import automap_base from sqlalchemy.ext.automap import generate_relationship from sqlalchemy.orm import configure_mappers +from sqlalchemy.orm import exc as orm_exc from sqlalchemy.orm import interfaces from sqlalchemy.orm import relationship +from sqlalchemy.orm import Session +from sqlalchemy.testing import assert_raises_message from sqlalchemy.testing import fixtures from sqlalchemy.testing.mock import Mock from sqlalchemy.testing.mock import patch @@ -54,6 +57,23 @@ class AutomapTest(fixtures.MappedTest): u1 = User(name="u1", addresses_collection=set([a1])) assert a1.user is u1 + def test_exception_prepare_not_called(self): + Base = automap_base(metadata=self.metadata) + + class User(Base): + __tablename__ = "users" + + s = Session() + + assert_raises_message( + orm_exc.UnmappedClassError, + "Class test.ext.test_automap.User is a subclass of AutomapBase. " + r"Mappings are not produced until the .prepare\(\) method is " + "called on the class hierarchy.", + s.query, + User, + ) + def test_relationship_explicit_override_m2o(self): Base = automap_base(metadata=self.metadata) |
