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.py481
1 files changed, 5 insertions, 476 deletions
diff --git a/test/orm/test_mapper.py b/test/orm/test_mapper.py
index ad0662887..54613c222 100644
--- a/test/orm/test_mapper.py
+++ b/test/orm/test_mapper.py
@@ -2,21 +2,18 @@
from test.lib.testing import assert_raises, assert_raises_message
import sqlalchemy as sa
-from test.lib import testing, pickleable
+from test.lib import testing
from sqlalchemy import MetaData, Integer, String, ForeignKey, func, util
from test.lib.schema import Table, Column
from sqlalchemy.engine import default
from sqlalchemy.orm import mapper, relationship, backref, \
create_session, class_mapper, configure_mappers, reconstructor, \
- validates, aliased, Mapper
-from sqlalchemy.orm import defer, deferred, synonym, attributes, \
- column_property, composite, relationship, dynamic_loader, \
- comparable_property, AttributeExtension, Session
-from sqlalchemy.orm.instrumentation import ClassManager
+ validates, aliased, defer, deferred, synonym, attributes, \
+ column_property, composite, dynamic_loader, \
+ comparable_property, Session
from test.lib.testing import eq_, AssertsCompiledSQL
from test.orm import _base, _fixtures
-from sqlalchemy import event
-from test.lib.assertsql import AllOf, CompiledSQL
+from test.lib.assertsql import CompiledSQL
class MapperTest(_fixtures.FixtureTest):
@@ -2198,475 +2195,7 @@ class NoLoadTest(_fixtures.FixtureTest):
)
-class AttributeExtensionTest(_base.MappedTest):
- @classmethod
- def define_tables(cls, metadata):
- Table('t1',
- metadata,
- Column('id', Integer, primary_key=True),
- Column('type', String(40)),
- Column('data', String(50))
-
- )
-
- @testing.resolve_artifact_names
- def test_cascading_extensions(self):
- ext_msg = []
-
- class Ex1(sa.orm.AttributeExtension):
- def set(self, state, value, oldvalue, initiator):
- ext_msg.append("Ex1 %r" % value)
- return "ex1" + value
-
- class Ex2(sa.orm.AttributeExtension):
- def set(self, state, value, oldvalue, initiator):
- ext_msg.append("Ex2 %r" % value)
- return "ex2" + value
-
- class A(_base.BasicEntity):
- pass
- class B(A):
- pass
- class C(B):
- pass
-
- mapper(A, t1, polymorphic_on=t1.c.type, polymorphic_identity='a', properties={
- 'data':column_property(t1.c.data, extension=Ex1())
- })
- mapper(B, polymorphic_identity='b', inherits=A)
- mc = mapper(C, polymorphic_identity='c', inherits=B, properties={
- 'data':column_property(t1.c.data, extension=Ex2())
- })
-
- a1 = A(data='a1')
- b1 = B(data='b1')
- c1 = C(data='c1')
-
- eq_(a1.data, 'ex1a1')
- eq_(b1.data, 'ex1b1')
- eq_(c1.data, 'ex2c1')
-
- a1.data = 'a2'
- b1.data='b2'
- c1.data = 'c2'
- eq_(a1.data, 'ex1a2')
- eq_(b1.data, 'ex1b2')
- eq_(c1.data, 'ex2c2')
-
- eq_(ext_msg, ["Ex1 'a1'", "Ex1 'b1'", "Ex2 'c1'", "Ex1 'a2'", "Ex1 'b2'", "Ex2 'c2'"])
-
-class MapperEventsTest(_fixtures.FixtureTest):
- run_inserts = None
-
- @testing.resolve_artifact_names
- def test_instance_event_listen(self):
- """test listen targets for instance events"""
-
- canary = []
- class A(object):
- pass
- class B(A):
- pass
-
- mapper(A, users)
- mapper(B, addresses, inherits=A)
-
- def init_a(target, args, kwargs):
- canary.append(('init_a', target))
-
- def init_b(target, args, kwargs):
- canary.append(('init_b', target))
-
- def init_c(target, args, kwargs):
- canary.append(('init_c', target))
-
- def init_d(target, args, kwargs):
- canary.append(('init_d', target))
-
- def init_e(target, args, kwargs):
- canary.append(('init_e', target))
-
- event.listen(mapper, 'init', init_a)
- event.listen(Mapper, 'init', init_b)
- event.listen(class_mapper(A), 'init', init_c)
- event.listen(A, 'init', init_d)
- event.listen(A, 'init', init_e, propagate=True)
-
- a = A()
- eq_(canary, [('init_a', a),('init_b', a),
- ('init_c', a),('init_d', a),('init_e', a)])
-
- # test propagate flag
- canary[:] = []
- b = B()
- eq_(canary, [('init_a', b), ('init_b', b),('init_e', b)])
-
- def teardown(self):
- # TODO: need to get remove() functionality
- # going
- Mapper.dispatch._clear()
- ClassManager.dispatch._clear()
- super(MapperEventsTest, self).teardown()
-
- def listen_all(self, mapper, **kw):
- canary = []
- def evt(meth):
- def go(*args, **kwargs):
- canary.append(meth)
- return go
-
- for meth in [
- 'init',
- 'init_failure',
- 'translate_row',
- 'create_instance',
- 'append_result',
- 'populate_instance',
- 'load',
- 'refresh',
- 'expire',
- 'before_insert',
- 'after_insert',
- 'before_update',
- 'after_update',
- 'before_delete',
- 'after_delete'
- ]:
- event.listen(mapper, meth, evt(meth), **kw)
- return canary
-
- @testing.resolve_artifact_names
- def test_basic(self):
-
- mapper(User, users)
- canary = self.listen_all(User)
-
- sess = create_session()
- u = User(name='u1')
- sess.add(u)
- sess.flush()
- sess.expire(u)
- u = sess.query(User).get(u.id)
- sess.expunge_all()
- u = sess.query(User).get(u.id)
- u.name = 'u1 changed'
- sess.flush()
- sess.delete(u)
- sess.flush()
- eq_(canary,
- ['init', 'before_insert',
- 'after_insert', 'expire', 'translate_row', 'populate_instance',
- 'refresh',
- 'append_result', 'translate_row', 'create_instance',
- 'populate_instance', 'load', 'append_result',
- 'before_update', 'after_update', 'before_delete', 'after_delete'])
-
- @testing.resolve_artifact_names
- def test_inheritance(self):
- class AdminUser(User):
- pass
-
- mapper(User, users)
- mapper(AdminUser, addresses, inherits=User)
-
- canary1 = self.listen_all(User, propagate=True)
- canary2 = self.listen_all(User)
- canary3 = self.listen_all(AdminUser)
-
- sess = create_session()
- am = AdminUser(name='au1', email_address='au1@e1')
- sess.add(am)
- sess.flush()
- am = sess.query(AdminUser).populate_existing().get(am.id)
- sess.expunge_all()
- am = sess.query(AdminUser).get(am.id)
- am.name = 'au1 changed'
- sess.flush()
- sess.delete(am)
- sess.flush()
- eq_(canary1, ['init', 'before_insert', 'after_insert',
- 'translate_row', 'populate_instance','refresh',
- 'append_result', 'translate_row', 'create_instance'
- , 'populate_instance', 'load', 'append_result',
- 'before_update', 'after_update', 'before_delete',
- 'after_delete'])
- eq_(canary2, [])
- eq_(canary3, ['init', 'before_insert', 'after_insert',
- 'translate_row', 'populate_instance','refresh',
- 'append_result', 'translate_row', 'create_instance'
- , 'populate_instance', 'load', 'append_result',
- 'before_update', 'after_update', 'before_delete',
- 'after_delete'])
-
- @testing.resolve_artifact_names
- def test_before_after_only_collection(self):
- """before_update is called on parent for collection modifications,
- after_update is called even if no columns were updated.
-
- """
-
- mapper(Item, items, properties={
- 'keywords': relationship(Keyword, secondary=item_keywords)})
- mapper(Keyword, keywords)
-
- canary1 = self.listen_all(Item)
- canary2 = self.listen_all(Keyword)
-
- sess = create_session()
- i1 = Item(description="i1")
- k1 = Keyword(name="k1")
- sess.add(i1)
- sess.add(k1)
- sess.flush()
- eq_(canary1,
- ['init',
- 'before_insert', 'after_insert'])
- eq_(canary2,
- ['init',
- 'before_insert', 'after_insert'])
-
- canary1[:]= []
- canary2[:]= []
-
- i1.keywords.append(k1)
- sess.flush()
- eq_(canary1, ['before_update', 'after_update'])
- eq_(canary2, [])
-
-
- @testing.resolve_artifact_names
- def test_retval(self):
- def create_instance(mapper, context, row, class_):
- u = User.__new__(User)
- u.foo = True
- return u
-
- mapper(User, users)
- event.listen(User, 'create_instance', create_instance, retval=True)
- sess = create_session()
- u1 = User()
- u1.name = 'ed'
- sess.add(u1)
- sess.flush()
- sess.expunge_all()
- u = sess.query(User).first()
- assert u.foo
-
- @testing.resolve_artifact_names
- def test_instrument_event(self):
- canary = []
- def instrument_class(mapper, cls):
- canary.append(cls)
-
- event.listen(Mapper, 'instrument_class', instrument_class)
-
- mapper(User, users)
- eq_(canary, [User])
- mapper(Address, addresses)
- eq_(canary, [User, Address])
-
-
-class MapperExtensionTest(_fixtures.FixtureTest):
- """Superceded by MapperEventsTest - test backwards
- compatiblity of MapperExtension."""
-
- run_inserts = None
-
- def extension(self):
- methods = []
-
- class Ext(sa.orm.MapperExtension):
- def instrument_class(self, mapper, cls):
- methods.append('instrument_class')
- return sa.orm.EXT_CONTINUE
-
- def init_instance(self, mapper, class_, oldinit, instance, args, kwargs):
- methods.append('init_instance')
- return sa.orm.EXT_CONTINUE
-
- def init_failed(self, mapper, class_, oldinit, instance, args, kwargs):
- methods.append('init_failed')
- return sa.orm.EXT_CONTINUE
-
- def translate_row(self, mapper, context, row):
- methods.append('translate_row')
- return sa.orm.EXT_CONTINUE
-
- def create_instance(self, mapper, selectcontext, row, class_):
- methods.append('create_instance')
- return sa.orm.EXT_CONTINUE
-
- def reconstruct_instance(self, mapper, instance):
- methods.append('reconstruct_instance')
- return sa.orm.EXT_CONTINUE
-
- def append_result(self, mapper, selectcontext, row, instance, result, **flags):
- methods.append('append_result')
- return sa.orm.EXT_CONTINUE
-
- def populate_instance(self, mapper, selectcontext, row, instance, **flags):
- methods.append('populate_instance')
- return sa.orm.EXT_CONTINUE
-
- def before_insert(self, mapper, connection, instance):
- methods.append('before_insert')
- return sa.orm.EXT_CONTINUE
-
- def after_insert(self, mapper, connection, instance):
- methods.append('after_insert')
- return sa.orm.EXT_CONTINUE
-
- def before_update(self, mapper, connection, instance):
- methods.append('before_update')
- return sa.orm.EXT_CONTINUE
-
- def after_update(self, mapper, connection, instance):
- methods.append('after_update')
- return sa.orm.EXT_CONTINUE
-
- def before_delete(self, mapper, connection, instance):
- methods.append('before_delete')
- return sa.orm.EXT_CONTINUE
-
- def after_delete(self, mapper, connection, instance):
- methods.append('after_delete')
- return sa.orm.EXT_CONTINUE
-
- return Ext, methods
-
- @testing.resolve_artifact_names
- def test_basic(self):
- """test that common user-defined methods get called."""
- Ext, methods = self.extension()
-
- mapper(User, users, extension=Ext())
- sess = create_session()
- u = User(name='u1')
- sess.add(u)
- sess.flush()
- u = sess.query(User).populate_existing().get(u.id)
- sess.expunge_all()
- u = sess.query(User).get(u.id)
- u.name = 'u1 changed'
- sess.flush()
- sess.delete(u)
- sess.flush()
- eq_(methods,
- ['instrument_class', 'init_instance', 'before_insert',
- 'after_insert', 'translate_row', 'populate_instance',
- 'append_result', 'translate_row', 'create_instance',
- 'populate_instance', 'reconstruct_instance', 'append_result',
- 'before_update', 'after_update', 'before_delete', 'after_delete'])
-
- @testing.resolve_artifact_names
- def test_inheritance(self):
- Ext, methods = self.extension()
-
- class AdminUser(User):
- pass
-
- mapper(User, users, extension=Ext())
- mapper(AdminUser, addresses, inherits=User)
-
- sess = create_session()
- am = AdminUser(name='au1', email_address='au1@e1')
- sess.add(am)
- sess.flush()
- am = sess.query(AdminUser).populate_existing().get(am.id)
- sess.expunge_all()
- am = sess.query(AdminUser).get(am.id)
- am.name = 'au1 changed'
- sess.flush()
- sess.delete(am)
- sess.flush()
- eq_(methods,
- ['instrument_class', 'instrument_class', 'init_instance',
- 'before_insert', 'after_insert', 'translate_row',
- 'populate_instance', 'append_result', 'translate_row',
- 'create_instance', 'populate_instance', 'reconstruct_instance',
- 'append_result', 'before_update', 'after_update', 'before_delete',
- 'after_delete'])
-
- @testing.resolve_artifact_names
- def test_before_after_only_collection(self):
- """before_update is called on parent for collection modifications,
- after_update is called even if no columns were updated.
- """
-
- Ext1, methods1 = self.extension()
- Ext2, methods2 = self.extension()
-
- mapper(Item, items, extension=Ext1() , properties={
- 'keywords': relationship(Keyword, secondary=item_keywords)})
- mapper(Keyword, keywords, extension=Ext2())
-
- sess = create_session()
- i1 = Item(description="i1")
- k1 = Keyword(name="k1")
- sess.add(i1)
- sess.add(k1)
- sess.flush()
- eq_(methods1,
- ['instrument_class', 'init_instance',
- 'before_insert', 'after_insert'])
- eq_(methods2,
- ['instrument_class', 'init_instance',
- 'before_insert', 'after_insert'])
-
- del methods1[:]
- del methods2[:]
- i1.keywords.append(k1)
- sess.flush()
- eq_(methods1, ['before_update', 'after_update'])
- eq_(methods2, [])
-
-
- @testing.resolve_artifact_names
- def test_inheritance_with_dupes(self):
- """Inheritance with the same extension instance on both mappers."""
- Ext, methods = self.extension()
-
- class AdminUser(User):
- pass
-
- ext = Ext()
- mapper(User, users, extension=ext)
- mapper(AdminUser, addresses, inherits=User, extension=ext)
-
- sess = create_session()
- am = AdminUser(name="au1", email_address="au1@e1")
- sess.add(am)
- sess.flush()
- am = sess.query(AdminUser).populate_existing().get(am.id)
- sess.expunge_all()
- am = sess.query(AdminUser).get(am.id)
- am.name = 'au1 changed'
- sess.flush()
- sess.delete(am)
- sess.flush()
- eq_(methods,
- ['instrument_class', 'instrument_class', 'init_instance',
- 'before_insert', 'after_insert', 'translate_row',
- 'populate_instance', 'append_result', 'translate_row',
- 'create_instance', 'populate_instance', 'reconstruct_instance',
- 'append_result', 'before_update', 'after_update', 'before_delete',
- 'after_delete'])
-
- @testing.resolve_artifact_names
- def test_create_instance(self):
- class CreateUserExt(sa.orm.MapperExtension):
- def create_instance(self, mapper, selectcontext, row, class_):
- return User.__new__(User)
-
- mapper(User, users, extension=CreateUserExt())
- sess = create_session()
- u1 = User()
- u1.name = 'ed'
- sess.add(u1)
- sess.flush()
- sess.expunge_all()
- assert sess.query(User).first()
class RequirementsTest(_base.MappedTest):