summaryrefslogtreecommitdiff
path: root/test/ext/declarative
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2014-01-21 20:10:23 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2014-01-21 20:10:23 -0500
commit07fb90c6cc14de6d02cf4be592c57d56831f59f7 (patch)
tree050ef65db988559c60f7aa40f2d0bfe24947e548 /test/ext/declarative
parent560fd1d5ed643a1b0f95296f3b840c1963bbe67f (diff)
parentee1f4d21037690ad996c5eacf7e1200e92f2fbaa (diff)
downloadsqlalchemy-ticket_2501.tar.gz
Merge branch 'master' into ticket_2501ticket_2501
Conflicts: lib/sqlalchemy/orm/mapper.py
Diffstat (limited to 'test/ext/declarative')
-rw-r--r--test/ext/declarative/test_basic.py157
-rw-r--r--test/ext/declarative/test_reflection.py132
2 files changed, 252 insertions, 37 deletions
diff --git a/test/ext/declarative/test_basic.py b/test/ext/declarative/test_basic.py
index 540f1623f..1f14d8164 100644
--- a/test/ext/declarative/test_basic.py
+++ b/test/ext/declarative/test_basic.py
@@ -4,14 +4,14 @@ from sqlalchemy.testing import eq_, assert_raises, \
from sqlalchemy.ext import declarative as decl
from sqlalchemy import exc
import sqlalchemy as sa
-from sqlalchemy import testing
+from sqlalchemy import testing, util
from sqlalchemy import MetaData, Integer, String, ForeignKey, \
ForeignKeyConstraint, Index
from sqlalchemy.testing.schema import Table, Column
from sqlalchemy.orm import relationship, create_session, class_mapper, \
joinedload, configure_mappers, backref, clear_mappers, \
deferred, column_property, composite,\
- Session
+ Session, properties
from sqlalchemy.testing import eq_
from sqlalchemy.util import classproperty, with_metaclass
from sqlalchemy.ext.declarative import declared_attr, AbstractConcreteBase, \
@@ -77,6 +77,26 @@ class DeclarativeTest(DeclarativeTestBase):
eq_(a1, Address(email='two'))
eq_(a1.user, User(name='u1'))
+ def test_unicode_string_resolve(self):
+ class User(Base, fixtures.ComparableEntity):
+ __tablename__ = 'users'
+
+ id = Column('id', Integer, primary_key=True,
+ test_needs_autoincrement=True)
+ name = Column('name', String(50))
+ addresses = relationship(util.u("Address"), backref="user")
+
+ class Address(Base, fixtures.ComparableEntity):
+ __tablename__ = 'addresses'
+
+ id = Column(Integer, primary_key=True,
+ test_needs_autoincrement=True)
+ email = Column(String(50), key='_email')
+ user_id = Column('user_id', Integer, ForeignKey('users.id'),
+ key='_user_id')
+
+ assert User.addresses.property.mapper.class_ is Address
+
def test_no_table(self):
def go():
class User(Base):
@@ -123,6 +143,71 @@ class DeclarativeTest(DeclarativeTestBase):
assert class_mapper(Bar).get_property('some_data').columns[0] \
is t.c.data
+ def test_column_named_twice(self):
+ def go():
+ class Foo(Base):
+ __tablename__ = 'foo'
+
+ id = Column(Integer, primary_key=True)
+ x = Column('x', Integer)
+ y = Column('x', Integer)
+ assert_raises_message(
+ sa.exc.SAWarning,
+ "On class 'Foo', Column object 'x' named directly multiple times, "
+ "only one will be used: x, y",
+ go
+ )
+
+
+ def test_column_repeated_under_prop(self):
+ def go():
+ class Foo(Base):
+ __tablename__ = 'foo'
+
+ id = Column(Integer, primary_key=True)
+ x = Column('x', Integer)
+ y = column_property(x)
+ z = Column('x', Integer)
+
+ assert_raises_message(
+ sa.exc.SAWarning,
+ "On class 'Foo', Column object 'x' named directly multiple times, "
+ "only one will be used: x, y, z",
+ go
+ )
+
+ def test_relationship_level_msg_for_invalid_callable(self):
+ class A(Base):
+ __tablename__ = 'a'
+ id = Column(Integer, primary_key=True)
+ class B(Base):
+ __tablename__ = 'b'
+ id = Column(Integer, primary_key=True)
+ a_id = Column(Integer, ForeignKey('a.id'))
+ a = relationship('a')
+ assert_raises_message(
+ sa.exc.ArgumentError,
+ "relationship 'a' expects a class or a mapper "
+ "argument .received: .*Table",
+ configure_mappers
+ )
+
+ def test_relationship_level_msg_for_invalid_object(self):
+ class A(Base):
+ __tablename__ = 'a'
+ id = Column(Integer, primary_key=True)
+ class B(Base):
+ __tablename__ = 'b'
+ id = Column(Integer, primary_key=True)
+ a_id = Column(Integer, ForeignKey('a.id'))
+ a = relationship(A.__table__)
+ assert_raises_message(
+ sa.exc.ArgumentError,
+ "relationship 'a' expects a class or a mapper "
+ "argument .received: .*Table",
+ configure_mappers
+ )
+
def test_difficult_class(self):
"""test no getattr() errors with a customized class"""
@@ -202,10 +287,10 @@ class DeclarativeTest(DeclarativeTestBase):
user = relationship("User", primaryjoin=user_id == User.id,
backref="addresses")
- assert mapperlib._new_mappers is True
+ assert mapperlib.Mapper._new_mappers is True
u = User()
assert User.addresses
- assert mapperlib._new_mappers is False
+ assert mapperlib.Mapper._new_mappers is False
def test_string_dependency_resolution(self):
from sqlalchemy.sql import desc
@@ -707,6 +792,64 @@ class DeclarativeTest(DeclarativeTestBase):
eq_(a1, Address(email='two'))
eq_(a1.user, User(name='u1'))
+ def test_alt_name_attr_subclass_column_inline(self):
+ # [ticket:2900]
+ class A(Base):
+ __tablename__ = 'a'
+ id = Column('id', Integer, primary_key=True)
+ data = Column('data')
+
+ class ASub(A):
+ brap = A.data
+ assert ASub.brap.property is A.data.property
+ assert isinstance(ASub.brap.original_property, properties.SynonymProperty)
+
+ def test_alt_name_attr_subclass_relationship_inline(self):
+ # [ticket:2900]
+ class A(Base):
+ __tablename__ = 'a'
+ id = Column('id', Integer, primary_key=True)
+ b_id = Column(Integer, ForeignKey('b.id'))
+ b = relationship("B", backref="as_")
+
+ class B(Base):
+ __tablename__ = 'b'
+ id = Column('id', Integer, primary_key=True)
+
+ configure_mappers()
+ class ASub(A):
+ brap = A.b
+ assert ASub.brap.property is A.b.property
+ assert isinstance(ASub.brap.original_property, properties.SynonymProperty)
+ ASub(brap=B())
+
+ def test_alt_name_attr_subclass_column_attrset(self):
+ # [ticket:2900]
+ class A(Base):
+ __tablename__ = 'a'
+ id = Column('id', Integer, primary_key=True)
+ data = Column('data')
+ A.brap = A.data
+ assert A.brap.property is A.data.property
+ assert isinstance(A.brap.original_property, properties.SynonymProperty)
+
+ def test_alt_name_attr_subclass_relationship_attrset(self):
+ # [ticket:2900]
+ class A(Base):
+ __tablename__ = 'a'
+ id = Column('id', Integer, primary_key=True)
+ b_id = Column(Integer, ForeignKey('b.id'))
+ b = relationship("B", backref="as_")
+ A.brap = A.b
+ class B(Base):
+ __tablename__ = 'b'
+ id = Column('id', Integer, primary_key=True)
+
+ assert A.brap.property is A.b.property
+ assert isinstance(A.brap.original_property, properties.SynonymProperty)
+ A(brap=B())
+
+
def test_eager_order_by(self):
class Address(Base, fixtures.ComparableEntity):
@@ -1276,8 +1419,10 @@ class DeclarativeTest(DeclarativeTestBase):
# case
sa.orm.configure_mappers()
- eq_(str(list(Address.user_id.property.columns[0].foreign_keys)[0]),
- "ForeignKey('users.id')")
+ eq_(
+ list(Address.user_id.property.columns[0].foreign_keys)[0].column,
+ User.__table__.c.id
+ )
Base.metadata.create_all()
u1 = User(name='u1', addresses=[Address(email='one'),
Address(email='two')])
diff --git a/test/ext/declarative/test_reflection.py b/test/ext/declarative/test_reflection.py
index 013439f93..f4bda6995 100644
--- a/test/ext/declarative/test_reflection.py
+++ b/test/ext/declarative/test_reflection.py
@@ -7,6 +7,8 @@ from sqlalchemy.orm import relationship, create_session, \
clear_mappers, \
Session
from sqlalchemy.testing import fixtures
+from sqlalchemy.testing.util import gc_collect
+from sqlalchemy.ext.declarative.base import _DeferredMapperConfig
class DeclarativeReflectionBase(fixtures.TablesTest):
__requires__ = 'reflectable_autoincrement',
@@ -47,9 +49,8 @@ class DeclarativeReflectionTest(DeclarativeReflectionBase):
test_needs_fk=True,
)
- def test_basic(self):
- meta = MetaData(testing.db)
+ def test_basic(self):
class User(Base, fixtures.ComparableEntity):
__tablename__ = 'users'
@@ -80,8 +81,6 @@ class DeclarativeReflectionTest(DeclarativeReflectionBase):
eq_(a1.user, User(name='u1'))
def test_rekey(self):
- meta = MetaData(testing.db)
-
class User(Base, fixtures.ComparableEntity):
__tablename__ = 'users'
@@ -114,8 +113,6 @@ class DeclarativeReflectionTest(DeclarativeReflectionBase):
assert_raises(TypeError, User, name='u3')
def test_supplied_fk(self):
- meta = MetaData(testing.db)
-
class IMHandle(Base, fixtures.ComparableEntity):
__tablename__ = 'imhandles'
@@ -151,9 +148,8 @@ class DeclarativeReflectionTest(DeclarativeReflectionBase):
class DeferredReflectBase(DeclarativeReflectionBase):
def teardown(self):
- super(DeferredReflectBase,self).teardown()
- from sqlalchemy.ext.declarative.base import _MapperConfig
- _MapperConfig.configs.clear()
+ super(DeferredReflectBase, self).teardown()
+ _DeferredMapperConfig._configs.clear()
Base = None
@@ -275,7 +271,7 @@ class DeferredReflectionTest(DeferredReflectBase):
@decl.declared_attr
def __mapper_args__(cls):
return {
- "order_by":cls.__table__.c.name
+ "order_by": cls.__table__.c.name
}
decl.DeferredReflection.prepare(testing.db)
@@ -297,6 +293,80 @@ class DeferredReflectionTest(DeferredReflectBase):
]
)
+ @testing.requires.predictable_gc
+ def test_cls_not_strong_ref(self):
+ class User(decl.DeferredReflection, fixtures.ComparableEntity,
+ Base):
+ __tablename__ = 'users'
+ class Address(decl.DeferredReflection, fixtures.ComparableEntity,
+ Base):
+ __tablename__ = 'addresses'
+ eq_(len(_DeferredMapperConfig._configs), 2)
+ del Address
+ gc_collect()
+ eq_(len(_DeferredMapperConfig._configs), 1)
+ decl.DeferredReflection.prepare(testing.db)
+ assert not _DeferredMapperConfig._configs
+
+class DeferredSecondaryReflectionTest(DeferredReflectBase):
+ @classmethod
+ def define_tables(cls, metadata):
+ Table('users', metadata,
+ Column('id', Integer,
+ primary_key=True, test_needs_autoincrement=True),
+ Column('name', String(50)), test_needs_fk=True)
+
+ Table('user_items', metadata,
+ Column('user_id', ForeignKey('users.id'), primary_key=True),
+ Column('item_id', ForeignKey('items.id'), primary_key=True),
+ test_needs_fk=True
+ )
+
+ Table('items', metadata,
+ Column('id', Integer, primary_key=True,
+ test_needs_autoincrement=True),
+ Column('name', String(50)),
+ test_needs_fk=True
+ )
+
+ def _roundtrip(self):
+
+ User = Base._decl_class_registry['User']
+ Item = Base._decl_class_registry['Item']
+
+ u1 = User(name='u1', items=[Item(name='i1'), Item(name='i2')])
+
+ sess = Session()
+ sess.add(u1)
+ sess.commit()
+
+ eq_(sess.query(User).all(), [User(name='u1',
+ items=[Item(name='i1'), Item(name='i2')])])
+
+ def test_string_resolution(self):
+ class User(decl.DeferredReflection, fixtures.ComparableEntity, Base):
+ __tablename__ = 'users'
+
+ items = relationship("Item", secondary="user_items")
+
+ class Item(decl.DeferredReflection, fixtures.ComparableEntity, Base):
+ __tablename__ = 'items'
+
+ decl.DeferredReflection.prepare(testing.db)
+ self._roundtrip()
+
+ def test_table_resolution(self):
+ class User(decl.DeferredReflection, fixtures.ComparableEntity, Base):
+ __tablename__ = 'users'
+
+ items = relationship("Item", secondary=Table("user_items", Base.metadata))
+
+ class Item(decl.DeferredReflection, fixtures.ComparableEntity, Base):
+ __tablename__ = 'items'
+
+ decl.DeferredReflection.prepare(testing.db)
+ self._roundtrip()
+
class DeferredInhReflectBase(DeferredReflectBase):
def _roundtrip(self):
Foo = Base._decl_class_registry['Foo']
@@ -338,11 +408,11 @@ class DeferredSingleInhReflectionTest(DeferredInhReflectBase):
class Foo(decl.DeferredReflection, fixtures.ComparableEntity,
Base):
__tablename__ = 'foo'
- __mapper_args__ = {"polymorphic_on":"type",
- "polymorphic_identity":"foo"}
+ __mapper_args__ = {"polymorphic_on": "type",
+ "polymorphic_identity": "foo"}
class Bar(Foo):
- __mapper_args__ = {"polymorphic_identity":"bar"}
+ __mapper_args__ = {"polymorphic_identity": "bar"}
decl.DeferredReflection.prepare(testing.db)
self._roundtrip()
@@ -351,11 +421,11 @@ class DeferredSingleInhReflectionTest(DeferredInhReflectBase):
class Foo(decl.DeferredReflection, fixtures.ComparableEntity,
Base):
__tablename__ = 'foo'
- __mapper_args__ = {"polymorphic_on":"type",
- "polymorphic_identity":"foo"}
+ __mapper_args__ = {"polymorphic_on": "type",
+ "polymorphic_identity": "foo"}
class Bar(Foo):
- __mapper_args__ = {"polymorphic_identity":"bar"}
+ __mapper_args__ = {"polymorphic_identity": "bar"}
bar_data = Column(String(30))
decl.DeferredReflection.prepare(testing.db)
@@ -365,12 +435,12 @@ class DeferredSingleInhReflectionTest(DeferredInhReflectBase):
class Foo(decl.DeferredReflection, fixtures.ComparableEntity,
Base):
__tablename__ = 'foo'
- __mapper_args__ = {"polymorphic_on":"type",
- "polymorphic_identity":"foo"}
+ __mapper_args__ = {"polymorphic_on": "type",
+ "polymorphic_identity": "foo"}
id = Column(Integer, primary_key=True)
class Bar(Foo):
- __mapper_args__ = {"polymorphic_identity":"bar"}
+ __mapper_args__ = {"polymorphic_identity": "bar"}
decl.DeferredReflection.prepare(testing.db)
self._roundtrip()
@@ -395,12 +465,12 @@ class DeferredJoinedInhReflectionTest(DeferredInhReflectBase):
class Foo(decl.DeferredReflection, fixtures.ComparableEntity,
Base):
__tablename__ = 'foo'
- __mapper_args__ = {"polymorphic_on":"type",
- "polymorphic_identity":"foo"}
+ __mapper_args__ = {"polymorphic_on": "type",
+ "polymorphic_identity": "foo"}
class Bar(Foo):
__tablename__ = 'bar'
- __mapper_args__ = {"polymorphic_identity":"bar"}
+ __mapper_args__ = {"polymorphic_identity": "bar"}
decl.DeferredReflection.prepare(testing.db)
self._roundtrip()
@@ -409,12 +479,12 @@ class DeferredJoinedInhReflectionTest(DeferredInhReflectBase):
class Foo(decl.DeferredReflection, fixtures.ComparableEntity,
Base):
__tablename__ = 'foo'
- __mapper_args__ = {"polymorphic_on":"type",
- "polymorphic_identity":"foo"}
+ __mapper_args__ = {"polymorphic_on": "type",
+ "polymorphic_identity": "foo"}
class Bar(Foo):
__tablename__ = 'bar'
- __mapper_args__ = {"polymorphic_identity":"bar"}
+ __mapper_args__ = {"polymorphic_identity": "bar"}
bar_data = Column(String(30))
decl.DeferredReflection.prepare(testing.db)
@@ -424,13 +494,13 @@ class DeferredJoinedInhReflectionTest(DeferredInhReflectBase):
class Foo(decl.DeferredReflection, fixtures.ComparableEntity,
Base):
__tablename__ = 'foo'
- __mapper_args__ = {"polymorphic_on":"type",
- "polymorphic_identity":"foo"}
+ __mapper_args__ = {"polymorphic_on": "type",
+ "polymorphic_identity": "foo"}
id = Column(Integer, primary_key=True)
class Bar(Foo):
__tablename__ = 'bar'
- __mapper_args__ = {"polymorphic_identity":"bar"}
+ __mapper_args__ = {"polymorphic_identity": "bar"}
decl.DeferredReflection.prepare(testing.db)
self._roundtrip()
@@ -439,12 +509,12 @@ class DeferredJoinedInhReflectionTest(DeferredInhReflectBase):
class Foo(decl.DeferredReflection, fixtures.ComparableEntity,
Base):
__tablename__ = 'foo'
- __mapper_args__ = {"polymorphic_on":"type",
- "polymorphic_identity":"foo"}
+ __mapper_args__ = {"polymorphic_on": "type",
+ "polymorphic_identity": "foo"}
class Bar(Foo):
__tablename__ = 'bar'
- __mapper_args__ = {"polymorphic_identity":"bar"}
+ __mapper_args__ = {"polymorphic_identity": "bar"}
id = Column(Integer, ForeignKey('foo.id'), primary_key=True)
decl.DeferredReflection.prepare(testing.db)