summaryrefslogtreecommitdiff
path: root/test/ext
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
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')
-rw-r--r--test/ext/declarative/test_basic.py157
-rw-r--r--test/ext/declarative/test_reflection.py132
-rw-r--r--test/ext/test_associationproxy.py190
-rw-r--r--test/ext/test_automap.py146
-rw-r--r--test/ext/test_compiler.py18
-rw-r--r--test/ext/test_extendedattr.py2
-rw-r--r--test/ext/test_mutable.py6
-rw-r--r--test/ext/test_serializer.py51
8 files changed, 561 insertions, 141 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)
diff --git a/test/ext/test_associationproxy.py b/test/ext/test_associationproxy.py
index 4cfb58481..3450eeb2f 100644
--- a/test/ext/test_associationproxy.py
+++ b/test/ext/test_associationproxy.py
@@ -9,7 +9,6 @@ from sqlalchemy.ext.associationproxy import *
from sqlalchemy.ext.associationproxy import _AssociationList
from sqlalchemy.testing import assert_raises_message
from sqlalchemy.testing.util import gc_collect
-from sqlalchemy.sql import not_
from sqlalchemy.testing import fixtures, AssertsCompiledSQL
from sqlalchemy import testing
from sqlalchemy.testing.schema import Table, Column
@@ -139,7 +138,7 @@ class _CollectionOperations(fixtures.TestBase):
self.assert_(len(p1._children) == 0)
self.assert_(len(p1.children) == 0)
- p1.children = ['a','b','c']
+ p1.children = ['a', 'b', 'c']
self.assert_(len(p1._children) == 3)
self.assert_(len(p1.children) == 3)
@@ -324,7 +323,7 @@ class CustomDictTest(DictTest):
self.assert_(len(p1._children) == 3)
self.assert_(len(p1.children) == 3)
- self.assert_(set(p1.children) == set(['d','e','f']))
+ self.assert_(set(p1.children) == set(['d', 'e', 'f']))
del ch
p1 = self.roundtrip(p1)
@@ -407,7 +406,7 @@ class SetTest(_CollectionOperations):
self.assert_(len(p1._children) == 0)
self.assert_(len(p1.children) == 0)
- p1.children = ['a','b','c']
+ p1.children = ['a', 'b', 'c']
self.assert_(len(p1._children) == 3)
self.assert_(len(p1.children) == 3)
@@ -421,13 +420,12 @@ class SetTest(_CollectionOperations):
self.assert_('b' in p1.children)
self.assert_('d' not in p1.children)
- self.assert_(p1.children == set(['a','b','c']))
+ self.assert_(p1.children == set(['a', 'b', 'c']))
- try:
- p1.children.remove('d')
- self.fail()
- except KeyError:
- pass
+ assert_raises(
+ KeyError,
+ p1.children.remove, "d"
+ )
self.assert_(len(p1.children) == 3)
p1.children.discard('d')
@@ -442,9 +440,9 @@ class SetTest(_CollectionOperations):
self.assert_(len(p1.children) == 2)
self.assert_(popped not in p1.children)
- p1.children = ['a','b','c']
+ p1.children = ['a', 'b', 'c']
p1 = self.roundtrip(p1)
- self.assert_(p1.children == set(['a','b','c']))
+ self.assert_(p1.children == set(['a', 'b', 'c']))
p1.children.discard('b')
p1 = self.roundtrip(p1)
@@ -476,12 +474,12 @@ class SetTest(_CollectionOperations):
Parent, Child = self.Parent, self.Child
p1 = Parent('P1')
- p1.children = ['a','b','c']
- control = set(['a','b','c'])
+ p1.children = ['a', 'b', 'c']
+ control = set(['a', 'b', 'c'])
- for other in (set(['a','b','c']), set(['a','b','c','d']),
- set(['a']), set(['a','b']),
- set(['c','d']), set(['e', 'f', 'g']),
+ for other in (set(['a', 'b', 'c']), set(['a', 'b', 'c', 'd']),
+ set(['a']), set(['a', 'b']),
+ set(['c', 'd']), set(['e', 'f', 'g']),
set()):
eq_(p1.children.union(other),
@@ -499,12 +497,12 @@ class SetTest(_CollectionOperations):
eq_(p1.children.issuperset(other),
control.issuperset(other))
- self.assert_((p1.children == other) == (control == other))
- self.assert_((p1.children != other) == (control != other))
- self.assert_((p1.children < other) == (control < other))
- self.assert_((p1.children <= other) == (control <= other))
- self.assert_((p1.children > other) == (control > other))
- self.assert_((p1.children >= other) == (control >= other))
+ self.assert_((p1.children == other) == (control == other))
+ self.assert_((p1.children != other) == (control != other))
+ self.assert_((p1.children < other) == (control < other))
+ self.assert_((p1.children <= other) == (control <= other))
+ self.assert_((p1.children > other) == (control > other))
+ self.assert_((p1.children >= other) == (control >= other))
def test_set_mutation(self):
Parent, Child = self.Parent, self.Child
@@ -513,9 +511,9 @@ class SetTest(_CollectionOperations):
for op in ('update', 'intersection_update',
'difference_update', 'symmetric_difference_update'):
for base in (['a', 'b', 'c'], []):
- for other in (set(['a','b','c']), set(['a','b','c','d']),
- set(['a']), set(['a','b']),
- set(['c','d']), set(['e', 'f', 'g']),
+ for other in (set(['a', 'b', 'c']), set(['a', 'b', 'c', 'd']),
+ set(['a']), set(['a', 'b']),
+ set(['c', 'd']), set(['e', 'f', 'g']),
set()):
p = Parent('p')
p.children = base[:]
@@ -544,9 +542,9 @@ class SetTest(_CollectionOperations):
# in-place mutations
for op in ('|=', '-=', '&=', '^='):
for base in (['a', 'b', 'c'], []):
- for other in (set(['a','b','c']), set(['a','b','c','d']),
- set(['a']), set(['a','b']),
- set(['c','d']), set(['e', 'f', 'g']),
+ for other in (set(['a', 'b', 'c']), set(['a', 'b', 'c', 'd']),
+ set(['a']), set(['a', 'b']),
+ set(['c', 'd']), set(['e', 'f', 'g']),
frozenset(['e', 'f', 'g']),
set()):
p = Parent('p')
@@ -599,12 +597,11 @@ class CustomObjectTest(_CollectionOperations):
# We didn't provide an alternate _AssociationList implementation
# for our ObjectCollection, so indexing will fail.
+ assert_raises(
+ TypeError,
+ p.children.__getitem__, 1
+ )
- try:
- v = p.children[1]
- self.fail()
- except TypeError:
- pass
class ProxyFactoryTest(ListTest):
def setup(self):
@@ -669,8 +666,9 @@ class ProxyFactoryTest(ListTest):
class ScalarTest(fixtures.TestBase):
+ @testing.provide_metadata
def test_scalar_proxy(self):
- metadata = MetaData(testing.db)
+ metadata = self.metadata
parents_table = Table('Parent', metadata,
Column('id', Integer, primary_key=True,
@@ -718,12 +716,8 @@ class ScalarTest(fixtures.TestBase):
p = Parent('p')
- # No child
- try:
- v = p.foo
- self.fail()
- except:
- pass
+ eq_(p.child, None)
+ eq_(p.foo, None)
p.child = Child(foo='a', bar='b', baz='c')
@@ -744,19 +738,13 @@ class ScalarTest(fixtures.TestBase):
p.child = None
- # No child again
- try:
- v = p.foo
- self.fail()
- except:
- pass
+ eq_(p.foo, None)
# Bogus creator for this scalar type
- try:
- p.foo = 'zzz'
- self.fail()
- except TypeError:
- pass
+ assert_raises(
+ TypeError,
+ setattr, p, "foo", "zzz"
+ )
p.bar = 'yyy'
@@ -786,6 +774,48 @@ class ScalarTest(fixtures.TestBase):
p2 = Parent('p2')
p2.bar = 'quux'
+ @testing.provide_metadata
+ def test_empty_scalars(self):
+ metadata = self.metadata
+
+ a = Table('a', metadata,
+ Column('id', Integer, primary_key=True),
+ Column('name', String(50))
+ )
+ a2b = Table('a2b', metadata,
+ Column('id', Integer, primary_key=True),
+ Column('id_a', Integer, ForeignKey('a.id')),
+ Column('id_b', Integer, ForeignKey('b.id')),
+ Column('name', String(50))
+ )
+ b = Table('b', metadata,
+ Column('id', Integer, primary_key=True),
+ Column('name', String(50))
+ )
+ class A(object):
+ a2b_name = association_proxy("a2b_single", "name")
+ b_single = association_proxy("a2b_single", "b")
+
+ class A2B(object):
+ pass
+
+ class B(object):
+ pass
+
+ mapper(A, a, properties=dict(
+ a2b_single=relationship(A2B, uselist=False)
+ ))
+
+ mapper(A2B, a2b, properties=dict(
+ b=relationship(B)
+ ))
+ mapper(B, b)
+
+ a1 = A()
+ assert a1.a2b_name is None
+ assert a1.b_single is None
+
+
class LazyLoadTest(fixtures.TestBase):
def setup(self):
@@ -840,7 +870,7 @@ class LazyLoadTest(fixtures.TestBase):
collection_class=list)})
p = Parent('p')
- p.children = ['a','b','c']
+ p.children = ['a', 'b', 'c']
p = self.roundtrip(p)
@@ -858,7 +888,7 @@ class LazyLoadTest(fixtures.TestBase):
collection_class=list)})
p = Parent('p')
- p.children = ['a','b','c']
+ p.children = ['a', 'b', 'c']
p = self.roundtrip(p)
@@ -1024,7 +1054,7 @@ class ComparatorTest(fixtures.MappedTest, AssertsCompiledSQL):
@classmethod
def define_tables(cls, metadata):
Table('userkeywords', metadata,
- Column('keyword_id', Integer,ForeignKey('keywords.id'), primary_key=True),
+ Column('keyword_id', Integer, ForeignKey('keywords.id'), primary_key=True),
Column('user_id', Integer, ForeignKey('users.id'))
)
Table('users', metadata,
@@ -1094,15 +1124,15 @@ class ComparatorTest(fixtures.MappedTest, AssertsCompiledSQL):
cls.classes.Singular)
mapper(User, users, properties={
- 'singular':relationship(Singular)
+ 'singular': relationship(Singular)
})
mapper(Keyword, keywords, properties={
- 'user_keyword':relationship(UserKeyword, uselist=False)
+ 'user_keyword': relationship(UserKeyword, uselist=False)
})
mapper(UserKeyword, userkeywords, properties={
- 'user' : relationship(User, backref='user_keywords'),
- 'keyword' : relationship(Keyword)
+ 'user': relationship(User, backref='user_keywords'),
+ 'keyword': relationship(Keyword)
})
mapper(Singular, singular, properties={
'keywords': relationship(Keyword)
@@ -1300,7 +1330,7 @@ class ComparatorTest(fixtures.MappedTest, AssertsCompiledSQL):
self.session.query(User).filter(User.singular_value == None),
self.session.query(User).filter(
or_(
- User.singular.has(Singular.value==None),
+ User.singular.has(Singular.value == None),
User.singular == None
)
)
@@ -1324,7 +1354,7 @@ class ComparatorTest(fixtures.MappedTest, AssertsCompiledSQL):
self._equivalent(
self.session.query(User).filter(User.singular_value == "singular4"),
self.session.query(User).filter(
- User.singular.has(Singular.value=="singular4"),
+ User.singular.has(Singular.value == "singular4"),
)
)
@@ -1343,7 +1373,7 @@ class ComparatorTest(fixtures.MappedTest, AssertsCompiledSQL):
# a special case where we provide an empty has() on a
# non-object-targeted association proxy.
User = self.classes.User
- Singular = self.classes.Singular
+ self.classes.Singular
self._equivalent(
self.session.query(User).filter(User.singular_value.has()),
@@ -1356,7 +1386,7 @@ class ComparatorTest(fixtures.MappedTest, AssertsCompiledSQL):
# a special case where we provide an empty has() on a
# non-object-targeted association proxy.
User = self.classes.User
- Singular = self.classes.Singular
+ self.classes.Singular
self._equivalent(
self.session.query(User).filter(~User.singular_value.has()),
@@ -1368,7 +1398,7 @@ class ComparatorTest(fixtures.MappedTest, AssertsCompiledSQL):
def test_has_criterion_nul(self):
# but we don't allow that with any criterion...
User = self.classes.User
- Singular = self.classes.Singular
+ self.classes.Singular
assert_raises_message(
exc.ArgumentError,
@@ -1380,7 +1410,7 @@ class ComparatorTest(fixtures.MappedTest, AssertsCompiledSQL):
def test_has_kwargs_nul(self):
# ... or kwargs
User = self.classes.User
- Singular = self.classes.Singular
+ self.classes.Singular
assert_raises_message(
exc.ArgumentError,
@@ -1391,32 +1421,32 @@ class ComparatorTest(fixtures.MappedTest, AssertsCompiledSQL):
def test_filter_scalar_contains_fails_nul_nul(self):
Keyword = self.classes.Keyword
- assert_raises(exc.InvalidRequestError, lambda : \
- Keyword.user.contains(self.u))
+ assert_raises(exc.InvalidRequestError,
+ lambda: Keyword.user.contains(self.u))
def test_filter_scalar_any_fails_nul_nul(self):
Keyword = self.classes.Keyword
- assert_raises(exc.InvalidRequestError, lambda : \
- Keyword.user.any(name='user2'))
+ assert_raises(exc.InvalidRequestError,
+ lambda: Keyword.user.any(name='user2'))
def test_filter_collection_has_fails_ul_nul(self):
User = self.classes.User
- assert_raises(exc.InvalidRequestError, lambda : \
- User.keywords.has(keyword='quick'))
+ assert_raises(exc.InvalidRequestError,
+ lambda: User.keywords.has(keyword='quick'))
def test_filter_collection_eq_fails_ul_nul(self):
User = self.classes.User
- assert_raises(exc.InvalidRequestError, lambda : \
- User.keywords == self.kw)
+ assert_raises(exc.InvalidRequestError,
+ lambda: User.keywords == self.kw)
def test_filter_collection_ne_fails_ul_nul(self):
User = self.classes.User
- assert_raises(exc.InvalidRequestError, lambda : \
- User.keywords != self.kw)
+ assert_raises(exc.InvalidRequestError,
+ lambda: User.keywords != self.kw)
def test_join_separate_attr(self):
User = self.classes.User
@@ -1458,7 +1488,7 @@ class DictOfTupleUpdateTest(fixtures.TestBase):
b = Table('b', m, Column('id', Integer, primary_key=True),
Column('aid', Integer, ForeignKey('a.id')))
mapper(A, a, properties={
- 'orig':relationship(B, collection_class=attribute_mapped_collection('key'))
+ 'orig': relationship(B, collection_class=attribute_mapped_collection('key'))
})
mapper(B, b)
self.A = A
@@ -1467,22 +1497,22 @@ class DictOfTupleUpdateTest(fixtures.TestBase):
def test_update_one_elem_dict(self):
a1 = self.A()
a1.elements.update({("B", 3): 'elem2'})
- eq_(a1.elements, {("B",3):'elem2'})
+ eq_(a1.elements, {("B", 3): 'elem2'})
def test_update_multi_elem_dict(self):
a1 = self.A()
a1.elements.update({("B", 3): 'elem2', ("C", 4): "elem3"})
- eq_(a1.elements, {("B",3):'elem2', ("C", 4): "elem3"})
+ eq_(a1.elements, {("B", 3): 'elem2', ("C", 4): "elem3"})
def test_update_one_elem_list(self):
a1 = self.A()
a1.elements.update([(("B", 3), 'elem2')])
- eq_(a1.elements, {("B",3):'elem2'})
+ eq_(a1.elements, {("B", 3): 'elem2'})
def test_update_multi_elem_list(self):
a1 = self.A()
a1.elements.update([(("B", 3), 'elem2'), (("C", 4), "elem3")])
- eq_(a1.elements, {("B",3):'elem2', ("C", 4): "elem3"})
+ eq_(a1.elements, {("B", 3): 'elem2', ("C", 4): "elem3"})
def test_update_one_elem_varg(self):
a1 = self.A()
diff --git a/test/ext/test_automap.py b/test/ext/test_automap.py
new file mode 100644
index 000000000..9db85879d
--- /dev/null
+++ b/test/ext/test_automap.py
@@ -0,0 +1,146 @@
+from sqlalchemy.testing import fixtures, eq_
+from ..orm._fixtures import FixtureTest
+from sqlalchemy.ext.automap import automap_base
+from sqlalchemy.orm import relationship, interfaces, backref
+from sqlalchemy.ext.automap import generate_relationship
+from sqlalchemy.testing.mock import Mock, call
+
+class AutomapTest(fixtures.MappedTest):
+ @classmethod
+ def define_tables(cls, metadata):
+ FixtureTest.define_tables(metadata)
+
+ def test_relationship_o2m_default(self):
+ Base = automap_base(metadata=self.metadata)
+ Base.prepare()
+
+ User = Base.classes.users
+ Address = Base.classes.addresses
+
+ a1 = Address(email_address='e1')
+ u1 = User(name='u1', addresses_collection=[a1])
+ assert a1.users is u1
+
+ def test_relationship_explicit_override_o2m(self):
+ Base = automap_base(metadata=self.metadata)
+ prop = relationship("addresses", collection_class=set)
+ class User(Base):
+ __tablename__ = 'users'
+
+ addresses_collection = prop
+
+ Base.prepare()
+ assert User.addresses_collection.property is prop
+ Address = Base.classes.addresses
+
+ a1 = Address(email_address='e1')
+ u1 = User(name='u1', addresses_collection=set([a1]))
+ assert a1.user is u1
+
+ def test_relationship_explicit_override_m2o(self):
+ Base = automap_base(metadata=self.metadata)
+
+ prop = relationship("users")
+ class Address(Base):
+ __tablename__ = 'addresses'
+
+ users = prop
+
+ Base.prepare()
+ User = Base.classes.users
+
+ assert Address.users.property is prop
+ a1 = Address(email_address='e1')
+ u1 = User(name='u1', address_collection=[a1])
+ assert a1.users is u1
+
+
+ def test_relationship_self_referential(self):
+ Base = automap_base(metadata=self.metadata)
+ Base.prepare()
+
+ Node = Base.classes.nodes
+
+ n1 = Node()
+ n2 = Node()
+ n1.nodes_collection.append(n2)
+ assert n2.nodes is n1
+
+ def test_naming_schemes(self):
+ Base = automap_base(metadata=self.metadata)
+
+ def classname_for_table(base, tablename, table):
+ return str("cls_" + tablename)
+
+ def name_for_scalar_relationship(base, local_cls, referred_cls, constraint):
+ return "scalar_" + referred_cls.__name__
+
+ def name_for_collection_relationship(base, local_cls, referred_cls, constraint):
+ return "coll_" + referred_cls.__name__
+
+ Base.prepare(
+ classname_for_table=classname_for_table,
+ name_for_scalar_relationship=name_for_scalar_relationship,
+ name_for_collection_relationship=name_for_collection_relationship
+ )
+
+ User = Base.classes.cls_users
+ Address = Base.classes.cls_addresses
+
+ u1 = User()
+ a1 = Address()
+ u1.coll_cls_addresses.append(a1)
+ assert a1.scalar_cls_users is u1
+
+ def test_relationship_m2m(self):
+ Base = automap_base(metadata=self.metadata)
+
+ Base.prepare()
+
+ Order, Item = Base.classes.orders, Base.classes['items']
+
+ o1 = Order()
+ i1 = Item()
+ o1.items_collection.append(i1)
+ assert o1 in i1.orders_collection
+
+ def test_relationship_explicit_override_forwards_m2m(self):
+ Base = automap_base(metadata=self.metadata)
+
+ class Order(Base):
+ __tablename__ = 'orders'
+
+ items_collection = relationship("items",
+ secondary="order_items",
+ collection_class=set)
+ Base.prepare()
+
+ Item = Base.classes['items']
+
+ o1 = Order()
+ i1 = Item()
+ o1.items_collection.add(i1)
+
+ # it's 'order_collection' because the class name is
+ # "Order" !
+ assert isinstance(i1.order_collection, list)
+ assert o1 in i1.order_collection
+
+ def test_relationship_pass_params(self):
+ Base = automap_base(metadata=self.metadata)
+
+ mock = Mock()
+ def _gen_relationship(base, direction, return_fn, attrname,
+ local_cls, referred_cls, **kw):
+ mock(base, direction, attrname)
+ return generate_relationship(base, direction, return_fn,
+ attrname, local_cls, referred_cls, **kw)
+
+ Base.prepare(generate_relationship=_gen_relationship)
+ assert set(tuple(c[1]) for c in mock.mock_calls).issuperset([
+ (Base, interfaces.MANYTOONE, "nodes"),
+ (Base, interfaces.MANYTOMANY, "keywords_collection"),
+ (Base, interfaces.MANYTOMANY, "items_collection"),
+ (Base, interfaces.MANYTOONE, "users"),
+ (Base, interfaces.ONETOMANY, "addresses_collection"),
+ ])
diff --git a/test/ext/test_compiler.py b/test/ext/test_compiler.py
index c1f8b6258..5ed50442f 100644
--- a/test/ext/test_compiler.py
+++ b/test/ext/test_compiler.py
@@ -4,7 +4,7 @@ from sqlalchemy.sql.expression import ClauseElement, ColumnClause,\
FunctionElement, Select, \
BindParameter
-from sqlalchemy.schema import DDLElement
+from sqlalchemy.schema import DDLElement, CreateColumn, CreateTable
from sqlalchemy.ext.compiler import compiles, deregister
from sqlalchemy import exc
from sqlalchemy.sql import table, column, visitors
@@ -34,6 +34,22 @@ class UserDefinedTest(fixtures.TestBase, AssertsCompiledSQL):
"SELECT >>x<<, >>y<< WHERE >>MYTHINGY!<< = :MYTHINGY!_1"
)
+ def test_create_column_skip(self):
+ @compiles(CreateColumn)
+ def skip_xmin(element, compiler, **kw):
+ if element.element.name == 'xmin':
+ return None
+ else:
+ return compiler.visit_create_column(element, **kw)
+
+ t = Table('t', MetaData(), Column('a', Integer),
+ Column('xmin', Integer),
+ Column('c', Integer))
+
+ self.assert_compile(
+ CreateTable(t),
+ "CREATE TABLE t (a INTEGER, c INTEGER)"
+ )
def test_types(self):
class MyType(TypeEngine):
pass
diff --git a/test/ext/test_extendedattr.py b/test/ext/test_extendedattr.py
index a550ae4d0..7a733696a 100644
--- a/test/ext/test_extendedattr.py
+++ b/test/ext/test_extendedattr.py
@@ -61,6 +61,8 @@ class MyTypesManager(instrumentation.InstrumentationManager):
class MyListLike(list):
# add @appender, @remover decorators as needed
_sa_iterator = list.__iter__
+ _sa_linker = None
+ _sa_converter = None
def _sa_appender(self, item, _sa_initiator=None):
if _sa_initiator is not False:
self._sa_adapter.fire_append_event(item, _sa_initiator)
diff --git a/test/ext/test_mutable.py b/test/ext/test_mutable.py
index 25c182f1d..ee1b8075e 100644
--- a/test/ext/test_mutable.py
+++ b/test/ext/test_mutable.py
@@ -153,9 +153,6 @@ class MutableWithScalarPickleTest(_MutableDictTestBase, fixtures.MappedTest):
self._test_non_mutable()
class MutableWithScalarJSONTest(_MutableDictTestBase, fixtures.MappedTest):
- # json introduced in 2.6
- __skip_if__ = lambda: sys.version_info < (2, 6),
-
@classmethod
def define_tables(cls, metadata):
import json
@@ -245,9 +242,6 @@ class MutableAssociationScalarPickleTest(_MutableDictTestBase, fixtures.MappedTe
)
class MutableAssociationScalarJSONTest(_MutableDictTestBase, fixtures.MappedTest):
- # json introduced in 2.6
- __skip_if__ = lambda: sys.version_info < (2, 6),
-
@classmethod
def define_tables(cls, metadata):
import json
diff --git a/test/ext/test_serializer.py b/test/ext/test_serializer.py
index 84fff1304..ffeac55c1 100644
--- a/test/ext/test_serializer.py
+++ b/test/ext/test_serializer.py
@@ -1,13 +1,15 @@
+# coding: utf-8
from sqlalchemy.ext import serializer
from sqlalchemy import testing
from sqlalchemy import Integer, String, ForeignKey, select, \
- desc, func, util
+ desc, func, util, MetaData
from sqlalchemy.testing.schema import Table
from sqlalchemy.testing.schema import Column
from sqlalchemy.orm import relationship, sessionmaker, scoped_session, \
class_mapper, mapper, joinedload, configure_mappers, aliased
-from sqlalchemy.testing import eq_
+from sqlalchemy.testing import eq_, AssertsCompiledSQL
+from sqlalchemy.util import u, ue
from sqlalchemy.testing import fixtures
@@ -19,7 +21,7 @@ class Address(fixtures.ComparableEntity):
users = addresses = Session = None
-class SerializeTest(fixtures.MappedTest):
+class SerializeTest(AssertsCompiledSQL, fixtures.MappedTest):
run_setup_mappers = 'once'
run_inserts = 'once'
@@ -77,7 +79,6 @@ class SerializeTest(fixtures.MappedTest):
assert serializer.loads(serializer.dumps(User.name, -1), None,
None) is User.name
- @testing.requires.python26 # crashes in 2.5
def test_expression(self):
expr = \
select([users]).select_from(users.join(addresses)).limit(5)
@@ -124,19 +125,20 @@ class SerializeTest(fixtures.MappedTest):
eq_(q2.all(), [User(name='fred')])
eq_(list(q2.values(User.id, User.name)), [(9, 'fred')])
- @testing.requires.non_broken_pickle
- def test_query_three(self):
- ua = aliased(User)
- q = \
- Session.query(ua).join(ua.addresses).\
- filter(Address.email.like('%fred%'))
- q2 = serializer.loads(serializer.dumps(q, -1), users.metadata,
- Session)
- eq_(q2.all(), [User(name='fred')])
-
+ # fails too often/randomly
+ #@testing.requires.non_broken_pickle
+ #def test_query_three(self):
+ # ua = aliased(User)
+ # q = \
+ # Session.query(ua).join(ua.addresses).\
+ # filter(Address.email.like('%fred%'))
+ # q2 = serializer.loads(serializer.dumps(q, -1), users.metadata,
+ # Session)
+ # eq_(q2.all(), [User(name='fred')])
+ #
# try to pull out the aliased entity here...
- ua_2 = q2._entities[0].entity_zero.entity
- eq_(list(q2.values(ua_2.id, ua_2.name)), [(9, 'fred')])
+ # ua_2 = q2._entities[0].entity_zero.entity
+ # eq_(list(q2.values(ua_2.id, ua_2.name)), [(9, 'fred')])
@testing.requires.non_broken_pickle
def test_orm_join(self):
@@ -149,7 +151,6 @@ class SerializeTest(fixtures.MappedTest):
assert j2.right is j.right
assert j2._target_adapter._next
- @testing.requires.python26 # namedtuple workaround not serializable in 2.5
@testing.exclude('sqlite', '<=', (3, 5, 9),
'id comparison failing on the buildbot')
def test_aliases(self):
@@ -172,6 +173,22 @@ class SerializeTest(fixtures.MappedTest):
x = serializer.loads(ser, users.metadata)
eq_(str(r), str(x))
+ def test_unicode(self):
+ m = MetaData()
+ t = Table(ue('\u6e2c\u8a66'), m,
+ Column(ue('\u6e2c\u8a66_id'), Integer))
+
+ expr = select([t]).where(t.c[ue('\u6e2c\u8a66_id')] == 5)
+
+ expr2 = serializer.loads(serializer.dumps(expr, -1), m)
+
+ self.assert_compile(
+ expr2,
+ ue('SELECT "\u6e2c\u8a66"."\u6e2c\u8a66_id" FROM "\u6e2c\u8a66" '
+ 'WHERE "\u6e2c\u8a66"."\u6e2c\u8a66_id" = :\u6e2c\u8a66_id_1'),
+ dialect="default"
+ )
+
if __name__ == '__main__':
testing.main()