summaryrefslogtreecommitdiff
path: root/test/orm/test_mapper.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/orm/test_mapper.py')
-rw-r--r--test/orm/test_mapper.py526
1 files changed, 35 insertions, 491 deletions
diff --git a/test/orm/test_mapper.py b/test/orm/test_mapper.py
index 06ec4ce27..32126e0dd 100644
--- a/test/orm/test_mapper.py
+++ b/test/orm/test_mapper.py
@@ -17,6 +17,7 @@ from sqlalchemy.testing import fixtures
from test.orm import _fixtures
from sqlalchemy.testing.assertsql import CompiledSQL
import logging
+import logging.handlers
class MapperTest(_fixtures.FixtureTest, AssertsCompiledSQL):
__dialect__ = 'default'
@@ -58,7 +59,7 @@ class MapperTest(_fixtures.FixtureTest, AssertsCompiledSQL):
addresses = self.tables.addresses
Address = self.classes.Address
- from sqlalchemy.orm.util import _is_mapped_class, _is_aliased_class
+ from sqlalchemy.orm.base import _is_mapped_class, _is_aliased_class
class Foo(object):
x = "something"
@@ -95,7 +96,7 @@ class MapperTest(_fixtures.FixtureTest, AssertsCompiledSQL):
def test_entity_descriptor(self):
users = self.tables.users
- from sqlalchemy.orm.util import _entity_descriptor
+ from sqlalchemy.orm.base import _entity_descriptor
class Foo(object):
x = "something"
@@ -195,16 +196,16 @@ class MapperTest(_fixtures.FixtureTest, AssertsCompiledSQL):
mapper(User, users)
sa.orm.configure_mappers()
- assert sa.orm.mapperlib._new_mappers is False
+ assert sa.orm.mapperlib.Mapper._new_mappers is False
m = mapper(Address, addresses, properties={
'user': relationship(User, backref="addresses")})
assert m.configured is False
- assert sa.orm.mapperlib._new_mappers is True
+ assert sa.orm.mapperlib.Mapper._new_mappers is True
u = User()
assert User.addresses
- assert sa.orm.mapperlib._new_mappers is False
+ assert sa.orm.mapperlib.Mapper._new_mappers is False
def test_configure_on_session(self):
User, users = self.classes.User, self.tables.users
@@ -302,6 +303,22 @@ class MapperTest(_fixtures.FixtureTest, AssertsCompiledSQL):
})
assert User.addresses.property is m.get_property('addresses')
+ def test_unicode_relationship_backref_names(self):
+ # test [ticket:2901]
+ users, Address, addresses, User = (self.tables.users,
+ self.classes.Address,
+ self.tables.addresses,
+ self.classes.User)
+
+ mapper(Address, addresses)
+ mapper(User, users, properties={
+ util.u('addresses'): relationship(Address, backref=util.u('user'))
+ })
+ u1 = User()
+ a1 = Address()
+ u1.addresses.append(a1)
+ assert a1.user is u1
+
def test_configure_on_prop_1(self):
users, Address, addresses, User = (self.tables.users,
self.classes.Address,
@@ -1566,6 +1583,13 @@ class MapperTest(_fixtures.FixtureTest, AssertsCompiledSQL):
class_mapper, 5
)
+ def test_unmapped_not_type_error_iter_ok(self):
+ assert_raises_message(
+ sa.exc.ArgumentError,
+ r"Class object expected, got '\(5, 6\)'.",
+ class_mapper, (5, 6)
+ )
+
def test_unmapped_subclass_error_postmap(self):
users = self.tables.users
@@ -1706,7 +1730,6 @@ class ORMLoggingTest(_fixtures.FixtureTest):
class OptionsTest(_fixtures.FixtureTest):
- @testing.fails_on('maxdb', 'FIXME: unknown')
def test_synonym_options(self):
Address, addresses, users, User = (self.classes.Address,
self.tables.addresses,
@@ -1749,7 +1772,6 @@ class OptionsTest(_fixtures.FixtureTest):
eq_(l, self.static.user_address_result)
self.sql_count_(0, go)
- @testing.fails_on('maxdb', 'FIXME: unknown')
def test_eager_options_with_limit(self):
Address, addresses, users, User = (self.classes.Address,
self.tables.addresses,
@@ -1775,7 +1797,6 @@ class OptionsTest(_fixtures.FixtureTest):
eq_(u.id, 8)
eq_(len(u.addresses), 3)
- @testing.fails_on('maxdb', 'FIXME: unknown')
def test_lazy_options_with_limit(self):
Address, addresses, users, User = (self.classes.Address,
self.tables.addresses,
@@ -1924,12 +1945,11 @@ class OptionsTest(_fixtures.FixtureTest):
oalias = aliased(Order)
opt1 = sa.orm.joinedload(User.orders, Order.items)
- opt2a, opt2b = sa.orm.contains_eager(User.orders, Order.items, alias=oalias)
- u1 = sess.query(User).join(oalias, User.orders).options(opt1, opt2a, opt2b).first()
+ opt2 = sa.orm.contains_eager(User.orders, Order.items, alias=oalias)
+ u1 = sess.query(User).join(oalias, User.orders).options(opt1, opt2).first()
ustate = attributes.instance_state(u1)
assert opt1 in ustate.load_options
- assert opt2a not in ustate.load_options
- assert opt2b not in ustate.load_options
+ assert opt2 not in ustate.load_options
class DeepOptionsTest(_fixtures.FixtureTest):
@@ -2038,139 +2058,6 @@ class DeepOptionsTest(_fixtures.FixtureTest):
x = u[0].orders[1].items[0].keywords[1]
self.sql_count_(2, go)
-class ValidatorTest(_fixtures.FixtureTest):
- def test_scalar(self):
- users = self.tables.users
- canary = []
- class User(fixtures.ComparableEntity):
- @validates('name')
- def validate_name(self, key, name):
- canary.append((key, name))
- assert name != 'fred'
- return name + ' modified'
-
- mapper(User, users)
- sess = create_session()
- u1 = User(name='ed')
- eq_(u1.name, 'ed modified')
- assert_raises(AssertionError, setattr, u1, "name", "fred")
- eq_(u1.name, 'ed modified')
- eq_(canary, [('name', 'ed'), ('name', 'fred')])
- sess.add(u1)
- sess.flush()
- sess.expunge_all()
- eq_(sess.query(User).filter_by(name='ed modified').one(), User(name='ed'))
-
- def test_collection(self):
- users, addresses, Address = (self.tables.users,
- self.tables.addresses,
- self.classes.Address)
-
- canary = []
- class User(fixtures.ComparableEntity):
- @validates('addresses')
- def validate_address(self, key, ad):
- canary.append((key, ad))
- assert '@' in ad.email_address
- return ad
-
- mapper(User, users, properties={'addresses':relationship(Address)})
- mapper(Address, addresses)
- sess = create_session()
- u1 = User(name='edward')
- a0 = Address(email_address='noemail')
- assert_raises(AssertionError, u1.addresses.append, a0)
- a1 = Address(id=15, email_address='foo@bar.com')
- u1.addresses.append(a1)
- eq_(canary, [('addresses', a0), ('addresses', a1)])
- sess.add(u1)
- sess.flush()
- sess.expunge_all()
- eq_(
- sess.query(User).filter_by(name='edward').one(),
- User(name='edward', addresses=[Address(email_address='foo@bar.com')])
- )
-
- def test_validators_dict(self):
- users, addresses, Address = (self.tables.users,
- self.tables.addresses,
- self.classes.Address)
-
- class User(fixtures.ComparableEntity):
-
- @validates('name')
- def validate_name(self, key, name):
- assert name != 'fred'
- return name + ' modified'
-
- @validates('addresses')
- def validate_address(self, key, ad):
- assert '@' in ad.email_address
- return ad
-
- def simple_function(self, key, value):
- return key, value
-
- u_m = mapper(User,
- users,
- properties={'addresses':relationship(Address)})
- mapper(Address, addresses)
-
- eq_(
- dict((k, v[0].__name__) for k, v in list(u_m.validators.items())),
- {'name':'validate_name',
- 'addresses':'validate_address'}
- )
-
- def test_validator_w_removes(self):
- users, addresses, Address = (self.tables.users,
- self.tables.addresses,
- self.classes.Address)
- canary = []
- class User(fixtures.ComparableEntity):
-
- @validates('name', include_removes=True)
- def validate_name(self, key, item, remove):
- canary.append((key, item, remove))
- return item
-
- @validates('addresses', include_removes=True)
- def validate_address(self, key, item, remove):
- canary.append((key, item, remove))
- return item
-
- mapper(User,
- users,
- properties={'addresses':relationship(Address)})
- mapper(Address, addresses)
-
- u1 = User()
- u1.name = "ed"
- u1.name = "mary"
- del u1.name
- a1, a2, a3 = Address(), Address(), Address()
- u1.addresses.append(a1)
- u1.addresses.remove(a1)
- u1.addresses = [a1, a2]
- u1.addresses = [a2, a3]
-
- eq_(canary, [
- ('name', 'ed', False),
- ('name', 'mary', False),
- ('name', 'mary', True),
- # append a1
- ('addresses', a1, False),
- # remove a1
- ('addresses', a1, True),
- # set to [a1, a2] - this is two appends
- ('addresses', a1, False), ('addresses', a2, False),
- # set to [a2, a3] - this is a remove of a1,
- # append of a3. the appends are first.
- ('addresses', a3, False),
- ('addresses', a1, True),
- ]
- )
-
class ComparatorFactoryTest(_fixtures.FixtureTest, AssertsCompiledSQL):
def test_kwarg_accepted(self):
users, Address = self.tables.users, self.classes.Address
@@ -2241,18 +2128,18 @@ class ComparatorFactoryTest(_fixtures.FixtureTest, AssertsCompiledSQL):
self.tables.addresses,
self.classes.User)
- from sqlalchemy.orm.properties import PropertyLoader
+ from sqlalchemy.orm.properties import RelationshipProperty
# NOTE: this API changed in 0.8, previously __clause_element__()
# gave the parent selecatable, now it gives the
# primaryjoin/secondaryjoin
- class MyFactory(PropertyLoader.Comparator):
+ class MyFactory(RelationshipProperty.Comparator):
__hash__ = None
def __eq__(self, other):
return func.foobar(self._source_selectable().c.user_id) == \
func.foobar(other.id)
- class MyFactory2(PropertyLoader.Comparator):
+ class MyFactory2(RelationshipProperty.Comparator):
__hash__ = None
def __eq__(self, other):
return func.foobar(self._source_selectable().c.id) == \
@@ -2285,349 +2172,6 @@ class ComparatorFactoryTest(_fixtures.FixtureTest, AssertsCompiledSQL):
dialect=default.DefaultDialect())
-class DeferredTest(_fixtures.FixtureTest):
-
- def test_basic(self):
- """A basic deferred load."""
-
- Order, orders = self.classes.Order, self.tables.orders
-
-
- mapper(Order, orders, order_by=orders.c.id, properties={
- 'description': deferred(orders.c.description)})
-
- o = Order()
- self.assert_(o.description is None)
-
- q = create_session().query(Order)
- def go():
- l = q.all()
- o2 = l[2]
- x = o2.description
-
- self.sql_eq_(go, [
- ("SELECT orders.id AS orders_id, "
- "orders.user_id AS orders_user_id, "
- "orders.address_id AS orders_address_id, "
- "orders.isopen AS orders_isopen "
- "FROM orders ORDER BY orders.id", {}),
- ("SELECT orders.description AS orders_description "
- "FROM orders WHERE orders.id = :param_1",
- {'param_1':3})])
-
- def test_unsaved(self):
- """Deferred loading does not kick in when just PK cols are set."""
-
- Order, orders = self.classes.Order, self.tables.orders
-
-
- mapper(Order, orders, properties={
- 'description': deferred(orders.c.description)})
-
- sess = create_session()
- o = Order()
- sess.add(o)
- o.id = 7
- def go():
- o.description = "some description"
- self.sql_count_(0, go)
-
- def test_synonym_group_bug(self):
- orders, Order = self.tables.orders, self.classes.Order
-
- mapper(Order, orders, properties={
- 'isopen':synonym('_isopen', map_column=True),
- 'description':deferred(orders.c.description, group='foo')
- })
-
- sess = create_session()
- o1 = sess.query(Order).get(1)
- eq_(o1.description, "order 1")
-
- def test_unsaved_2(self):
- Order, orders = self.classes.Order, self.tables.orders
-
- mapper(Order, orders, properties={
- 'description': deferred(orders.c.description)})
-
- sess = create_session()
- o = Order()
- sess.add(o)
- def go():
- o.description = "some description"
- self.sql_count_(0, go)
-
- def test_unsaved_group(self):
- """Deferred loading doesnt kick in when just PK cols are set"""
-
- orders, Order = self.tables.orders, self.classes.Order
-
-
- mapper(Order, orders, order_by=orders.c.id, properties=dict(
- description=deferred(orders.c.description, group='primary'),
- opened=deferred(orders.c.isopen, group='primary')))
-
- sess = create_session()
- o = Order()
- sess.add(o)
- o.id = 7
- def go():
- o.description = "some description"
- self.sql_count_(0, go)
-
- def test_unsaved_group_2(self):
- orders, Order = self.tables.orders, self.classes.Order
-
- mapper(Order, orders, order_by=orders.c.id, properties=dict(
- description=deferred(orders.c.description, group='primary'),
- opened=deferred(orders.c.isopen, group='primary')))
-
- sess = create_session()
- o = Order()
- sess.add(o)
- def go():
- o.description = "some description"
- self.sql_count_(0, go)
-
- def test_save(self):
- Order, orders = self.classes.Order, self.tables.orders
-
- m = mapper(Order, orders, properties={
- 'description': deferred(orders.c.description)})
-
- sess = create_session()
- o2 = sess.query(Order).get(2)
- o2.isopen = 1
- sess.flush()
-
- def test_group(self):
- """Deferred load with a group"""
-
- orders, Order = self.tables.orders, self.classes.Order
-
- mapper(Order, orders, properties=util.OrderedDict([
- ('userident', deferred(orders.c.user_id, group='primary')),
- ('addrident', deferred(orders.c.address_id, group='primary')),
- ('description', deferred(orders.c.description, group='primary')),
- ('opened', deferred(orders.c.isopen, group='primary'))
- ]))
-
- sess = create_session()
- q = sess.query(Order).order_by(Order.id)
- def go():
- l = q.all()
- o2 = l[2]
- eq_(o2.opened, 1)
- eq_(o2.userident, 7)
- eq_(o2.description, 'order 3')
-
- self.sql_eq_(go, [
- ("SELECT orders.id AS orders_id "
- "FROM orders ORDER BY orders.id", {}),
- ("SELECT orders.user_id AS orders_user_id, "
- "orders.address_id AS orders_address_id, "
- "orders.description AS orders_description, "
- "orders.isopen AS orders_isopen "
- "FROM orders WHERE orders.id = :param_1",
- {'param_1':3})])
-
- o2 = q.all()[2]
- eq_(o2.description, 'order 3')
- assert o2 not in sess.dirty
- o2.description = 'order 3'
- def go():
- sess.flush()
- self.sql_count_(0, go)
-
- def test_preserve_changes(self):
- """A deferred load operation doesn't revert modifications on attributes"""
-
- orders, Order = self.tables.orders, self.classes.Order
-
- mapper(Order, orders, properties = {
- 'userident': deferred(orders.c.user_id, group='primary'),
- 'description': deferred(orders.c.description, group='primary'),
- 'opened': deferred(orders.c.isopen, group='primary')
- })
- sess = create_session()
- o = sess.query(Order).get(3)
- assert 'userident' not in o.__dict__
- o.description = 'somenewdescription'
- eq_(o.description, 'somenewdescription')
- def go():
- eq_(o.opened, 1)
- self.assert_sql_count(testing.db, go, 1)
- eq_(o.description, 'somenewdescription')
- assert o in sess.dirty
-
- def test_commits_state(self):
- """
- When deferred elements are loaded via a group, they get the proper
- CommittedState and don't result in changes being committed
-
- """
-
- orders, Order = self.tables.orders, self.classes.Order
-
- mapper(Order, orders, properties = {
- 'userident':deferred(orders.c.user_id, group='primary'),
- 'description':deferred(orders.c.description, group='primary'),
- 'opened':deferred(orders.c.isopen, group='primary')})
-
- sess = create_session()
- o2 = sess.query(Order).get(3)
-
- # this will load the group of attributes
- eq_(o2.description, 'order 3')
- assert o2 not in sess.dirty
- # this will mark it as 'dirty', but nothing actually changed
- o2.description = 'order 3'
- # therefore the flush() shouldnt actually issue any SQL
- self.assert_sql_count(testing.db, sess.flush, 0)
-
- def test_options(self):
- """Options on a mapper to create deferred and undeferred columns"""
-
- orders, Order = self.tables.orders, self.classes.Order
-
-
- mapper(Order, orders)
-
- sess = create_session()
- q = sess.query(Order).order_by(Order.id).options(defer('user_id'))
-
- def go():
- q.all()[0].user_id
-
- self.sql_eq_(go, [
- ("SELECT orders.id AS orders_id, "
- "orders.address_id AS orders_address_id, "
- "orders.description AS orders_description, "
- "orders.isopen AS orders_isopen "
- "FROM orders ORDER BY orders.id", {}),
- ("SELECT orders.user_id AS orders_user_id "
- "FROM orders WHERE orders.id = :param_1",
- {'param_1':1})])
- sess.expunge_all()
-
- q2 = q.options(sa.orm.undefer('user_id'))
- self.sql_eq_(q2.all, [
- ("SELECT orders.id AS orders_id, "
- "orders.user_id AS orders_user_id, "
- "orders.address_id AS orders_address_id, "
- "orders.description AS orders_description, "
- "orders.isopen AS orders_isopen "
- "FROM orders ORDER BY orders.id",
- {})])
-
- def test_undefer_group(self):
- orders, Order = self.tables.orders, self.classes.Order
-
- mapper(Order, orders, properties=util.OrderedDict([
- ('userident',deferred(orders.c.user_id, group='primary')),
- ('description',deferred(orders.c.description, group='primary')),
- ('opened',deferred(orders.c.isopen, group='primary'))
- ]
- ))
-
- sess = create_session()
- q = sess.query(Order).order_by(Order.id)
- def go():
- l = q.options(sa.orm.undefer_group('primary')).all()
- o2 = l[2]
- eq_(o2.opened, 1)
- eq_(o2.userident, 7)
- eq_(o2.description, 'order 3')
-
- self.sql_eq_(go, [
- ("SELECT orders.user_id AS orders_user_id, "
- "orders.description AS orders_description, "
- "orders.isopen AS orders_isopen, "
- "orders.id AS orders_id, "
- "orders.address_id AS orders_address_id "
- "FROM orders ORDER BY orders.id",
- {})])
-
- def test_locates_col(self):
- """Manually adding a column to the result undefers the column."""
-
- orders, Order = self.tables.orders, self.classes.Order
-
-
- mapper(Order, orders, properties={
- 'description':deferred(orders.c.description)})
-
- sess = create_session()
- o1 = sess.query(Order).order_by(Order.id).first()
- def go():
- eq_(o1.description, 'order 1')
- self.sql_count_(1, go)
-
- sess = create_session()
- o1 = (sess.query(Order).
- order_by(Order.id).
- add_column(orders.c.description).first())[0]
- def go():
- eq_(o1.description, 'order 1')
- self.sql_count_(0, go)
-
- def test_map_selectable_wo_deferred(self):
- """test mapping to a selectable with deferred cols,
- the selectable doesn't include the deferred col.
-
- """
-
- Order, orders = self.classes.Order, self.tables.orders
-
-
- order_select = sa.select([
- orders.c.id,
- orders.c.user_id,
- orders.c.address_id,
- orders.c.description,
- orders.c.isopen]).alias()
- mapper(Order, order_select, properties={
- 'description':deferred(order_select.c.description)
- })
-
- sess = Session()
- o1 = sess.query(Order).order_by(Order.id).first()
- assert 'description' not in o1.__dict__
- eq_(o1.description, 'order 1')
-
- def test_deep_options(self):
- users, items, order_items, Order, Item, User, orders = (self.tables.users,
- self.tables.items,
- self.tables.order_items,
- self.classes.Order,
- self.classes.Item,
- self.classes.User,
- self.tables.orders)
-
- mapper(Item, items, properties=dict(
- description=deferred(items.c.description)))
- mapper(Order, orders, properties=dict(
- items=relationship(Item, secondary=order_items)))
- mapper(User, users, properties=dict(
- orders=relationship(Order, order_by=orders.c.id)))
-
- sess = create_session()
- q = sess.query(User).order_by(User.id)
- l = q.all()
- item = l[0].orders[1].items[1]
- def go():
- eq_(item.description, 'item 4')
- self.sql_count_(1, go)
- eq_(item.description, 'item 4')
-
- sess.expunge_all()
- l = q.options(sa.orm.undefer('orders.items.description')).all()
- item = l[0].orders[1].items[1]
- def go():
- eq_(item.description, 'item 4')
- self.sql_count_(0, go)
- eq_(item.description, 'item 4')
-
class SecondaryOptionsTest(fixtures.MappedTest):
"""test that the contains_eager() option doesn't bleed into a secondary load."""