summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authormike bayer <mike_mp@zzzcomputing.com>2019-01-31 16:09:41 +0000
committerGerrit Code Review <gerrit@bbpush.zzzcomputing.com>2019-01-31 16:09:41 +0000
commit7e48d8b2a70b399ffa6ec874f824d6cee82980a0 (patch)
tree54d6986ee5c2a56f8d9f374248f5a59301ebadb5 /test
parent06d952950975f71d86a43bbc4f2cbd9edccbc7ee (diff)
parent147f6d382c3b6f06c8efa5a24c07c9849473e7af (diff)
downloadsqlalchemy-7e48d8b2a70b399ffa6ec874f824d6cee82980a0.tar.gz
Merge "Add informative failure modes to _DeferredMapperConfig"
Diffstat (limited to 'test')
-rw-r--r--test/ext/declarative/test_basic.py33
-rw-r--r--test/ext/declarative/test_inheritance.py63
-rw-r--r--test/ext/declarative/test_reflection.py22
-rw-r--r--test/ext/test_automap.py20
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)