diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2010-01-13 17:11:27 +0000 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2010-01-13 17:11:27 +0000 |
| commit | 3c1a8adc782b9440b3e7e350712cdfa231c56f7f (patch) | |
| tree | ec54c4be11682f6221fab4a744c83a28bd188e30 | |
| parent | fccc3774171f1cbf6490363fe9d20d8cc9d78827 (diff) | |
| download | sqlalchemy-3c1a8adc782b9440b3e7e350712cdfa231c56f7f.tar.gz | |
NamedTuple is pickleable ! no really with all the protocols too !
| -rw-r--r-- | lib/sqlalchemy/orm/query.py | 5 | ||||
| -rw-r--r-- | lib/sqlalchemy/util.py | 7 | ||||
| -rw-r--r-- | test/orm/test_pickled.py | 21 | ||||
| -rw-r--r-- | test/orm/test_query.py | 29 |
4 files changed, 43 insertions, 19 deletions
diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index bd9069e3a..fc83f9195 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -1375,8 +1375,7 @@ class Query(object): elif single_entity: rows = [process[0](row, None) for row in fetch] else: - rows = [util.NamedTuple(labels, - [proc(row, None) for proc in process]) + rows = [util.NamedTuple([proc(row, None) for proc in process], labels) for row in fetch] if filter: @@ -1445,7 +1444,7 @@ class Query(object): attributes.instance_state(newrow[i]), attributes.instance_dict(newrow[i]), load=load, _recursive={}) - result.append(util.NamedTuple(row._labels, newrow)) + result.append(util.NamedTuple(newrow, row._labels)) return iter(result) finally: diff --git a/lib/sqlalchemy/util.py b/lib/sqlalchemy/util.py index f7d696971..c3ae25589 100644 --- a/lib/sqlalchemy/util.py +++ b/lib/sqlalchemy/util.py @@ -642,11 +642,12 @@ class NamedTuple(tuple): """ - def __new__(cls, labels, vals): + def __new__(cls, vals, labels=None): vals = list(vals) t = tuple.__new__(cls, vals) - t.__dict__ = dict(itertools.izip(labels, vals)) - t._labels = labels + if labels: + t.__dict__ = dict(itertools.izip(labels, vals)) + t._labels = labels return t def keys(self): diff --git a/test/orm/test_pickled.py b/test/orm/test_pickled.py index 1fcd1b8a4..0285f4d0b 100644 --- a/test/orm/test_pickled.py +++ b/test/orm/test_pickled.py @@ -4,7 +4,7 @@ import sqlalchemy as sa from sqlalchemy.test import testing from sqlalchemy import Integer, String, ForeignKey from sqlalchemy.test.schema import Table, Column -from sqlalchemy.orm import mapper, relation, create_session, attributes, interfaces +from sqlalchemy.orm import mapper, relation, create_session, sessionmaker, attributes, interfaces from test.orm import _base, _fixtures @@ -131,6 +131,25 @@ class PickleTest(_fixtures.FixtureTest): eq_(u2, User(name='ed', addresses=[Address(email_address='ed@bar.com')])) @testing.resolve_artifact_names + def test_pickle_protocols(self): + mapper(User, users, properties={ + 'addresses':relation(Address, backref="user") + }) + mapper(Address, addresses) + + sess = sessionmaker()() + u1 = User(name='ed') + u1.addresses.append(Address(email_address='ed@bar.com')) + sess.add(u1) + sess.commit() + + u1 = sess.query(User).first() + u1.addresses + for protocol in -1, 0, 1, 2: + u2 = pickle.loads(pickle.dumps(u1, protocol)) + eq_(u1, u2) + + @testing.resolve_artifact_names def test_options_with_descriptors(self): mapper(User, users, properties={ 'addresses':relation(Address, backref="user") diff --git a/test/orm/test_query.py b/test/orm/test_query.py index bc3b9e26d..ee9f1853b 100644 --- a/test/orm/test_query.py +++ b/test/orm/test_query.py @@ -2403,44 +2403,49 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL): def test_tuple_labeling(self): sess = create_session() - for pickled in False, True: + # test pickle + all the protocols ! + for pickled in False, -1, 0, 1, 2: for row in sess.query(User, Address).join(User.addresses).all(): - if pickled: - row = util.pickle.loads(util.pickle.dumps(row)) + if pickled is not False: + row = util.pickle.loads(util.pickle.dumps(row, pickled)) eq_(set(row.keys()), set(['User', 'Address'])) eq_(row.User, row[0]) eq_(row.Address, row[1]) for row in sess.query(User.name, User.id.label('foobar')): - if pickled: - row = util.pickle.loads(util.pickle.dumps(row)) + if pickled is not False: + row = util.pickle.loads(util.pickle.dumps(row, pickled)) eq_(set(row.keys()), set(['name', 'foobar'])) eq_(row.name, row[0]) eq_(row.foobar, row[1]) for row in sess.query(User).values(User.name, User.id.label('foobar')): - if pickled: - row = util.pickle.loads(util.pickle.dumps(row)) + if pickled is not False: + row = util.pickle.loads(util.pickle.dumps(row, pickled)) eq_(set(row.keys()), set(['name', 'foobar'])) eq_(row.name, row[0]) eq_(row.foobar, row[1]) oalias = aliased(Order) for row in sess.query(User, oalias).join(User.orders).all(): - if pickled: - row = util.pickle.loads(util.pickle.dumps(row)) + if pickled is not False: + row = util.pickle.loads(util.pickle.dumps(row, pickled)) eq_(set(row.keys()), set(['User'])) eq_(row.User, row[0]) oalias = aliased(Order, name='orders') for row in sess.query(User, oalias).join(User.orders).all(): - if pickled: - row = util.pickle.loads(util.pickle.dumps(row)) + if pickled is not False: + row = util.pickle.loads(util.pickle.dumps(row, pickled)) eq_(set(row.keys()), set(['User', 'orders'])) eq_(row.User, row[0]) eq_(row.orders, row[1]) - + + if pickled is not False: + ret = sess.query(User, Address).join(User.addresses).all() + util.pickle.loads(util.pickle.dumps(ret, pickled)) + def test_column_queries(self): sess = create_session() |
