- sqlalchemy.orm.join and sqlalchemy.orm.outerjoin are now

added to __all__ in sqlalchemy.orm.*. [ticket:1463]

- Fixed bug where Query exception raise would fail when
a too-short composite primary key value were passed to
get().  [ticket:1458]

- rearranged CHANGES for 0.5.5 to be somewhat severity based.

- commented on [ticket:1445]
This commit is contained in:
Mike Bayer
2009-07-12 14:33:06 +00:00
parent eeecbb8fc6
commit d99c0a9ecc
5 changed files with 81 additions and 42 deletions
+46 -39
View File
@@ -12,45 +12,6 @@ CHANGES
[ticket:970]
- orm
- Session.mapper is now *deprecated*.
Call session.add() if you'd like a free-standing object to be
part of your session. Otherwise, a DIY version of
Session.mapper is now documented at
http://www.sqlalchemy.org/trac/wiki/UsageRecipes/SessionAwareMapper
The method will remain deprecated throughout 0.6.
- Fixed bug introduced in 0.5.4 whereby Composite types fail
when default-holding columns are flushed.
- Fixed a bug involving contains_eager(), which would apply
itself to a secondary (i.e. lazy) load in a particular rare
case, producing cartesian products. improved the targeting of
query.options() on secondary loads overall [ticket:1461].
- Fixed another 0.5.4 bug whereby mutable attributes
(i.e. PickleType) wouldn't be deserialized correctly when the
whole object was serialized. [ticket:1426]
- Fixed bug whereby session.is_modified() would raise an
exception if any synonyms were in use.
- Fixed potential memory leak whereby previously pickled objects
placed back in a session would not be fully garbage collected
unless the Session were explicitly closed out.
- Fixed Query being able to join() from individual columns of a
joined-table subclass entity, i.e. query(SubClass.foo,
SubcClass.bar).join(<anything>). In most cases, an error
"Could not find a FROM clause to join from" would be
raised. In a few others, the result would be returned in terms
of the base class rather than the subclass - so applications
which relied on this erroneous result need to be
adjusted. [ticket:1431]
- Fixed bug whereby list-based attributes, like pickletype and
PGArray, failed to be merged() properly.
- The "foreign_keys" argument of relation() will now propagate
automatically to the backref in the same way that primaryjoin
and secondaryjoin do. For the extremely rare use case where
@@ -66,6 +27,45 @@ CHANGES
that the fk->itself aspect of the relation won't be used to
determine relation direction.
- Session.mapper is now *deprecated*.
Call session.add() if you'd like a free-standing object to be
part of your session. Otherwise, a DIY version of
Session.mapper is now documented at
http://www.sqlalchemy.org/trac/wiki/UsageRecipes/SessionAwareMapper
The method will remain deprecated throughout 0.6.
- Fixed Query being able to join() from individual columns of a
joined-table subclass entity, i.e. query(SubClass.foo,
SubcClass.bar).join(<anything>). In most cases, an error
"Could not find a FROM clause to join from" would be
raised. In a few others, the result would be returned in terms
of the base class rather than the subclass - so applications
which relied on this erroneous result need to be
adjusted. [ticket:1431]
- Fixed a bug involving contains_eager(), which would apply
itself to a secondary (i.e. lazy) load in a particular rare
case, producing cartesian products. improved the targeting of
query.options() on secondary loads overall [ticket:1461].
- Fixed bug introduced in 0.5.4 whereby Composite types fail
when default-holding columns are flushed.
- Fixed another 0.5.4 bug whereby mutable attributes
(i.e. PickleType) wouldn't be deserialized correctly when the
whole object was serialized. [ticket:1426]
- Fixed bug whereby session.is_modified() would raise an
exception if any synonyms were in use.
- Fixed potential memory leak whereby previously pickled objects
placed back in a session would not be fully garbage collected
unless the Session were explicitly closed out.
- Fixed bug whereby list-based attributes, like pickletype and
PGArray, failed to be merged() properly.
- Repaired non-working attributes.set_committed_value function.
- Trimmed the pickle format for InstanceState which should
@@ -73,6 +73,13 @@ CHANGES
format should be backwards compatible with that of 0.5.4 and
previous.
- sqlalchemy.orm.join and sqlalchemy.orm.outerjoin are now
added to __all__ in sqlalchemy.orm.*. [ticket:1463]
- Fixed bug where Query exception raise would fail when
a too-short composite primary key value were passed to
get(). [ticket:1458]
- sql
- Removed an obscure feature of execute() (including connection,
engine, Session) whereby a bindparam() construct can be sent
+2
View File
@@ -81,11 +81,13 @@ __all__ = (
'eagerload',
'eagerload_all',
'extension',
'join',
'lazyload',
'mapper',
'noload',
'object_mapper',
'object_session',
'outerjoin',
'polymorphic_union',
'reconstructor',
'relation',
+3 -2
View File
@@ -972,7 +972,8 @@ class Query(object):
# TODO:
# this provides one kind of "backwards join"
# tested in test/orm/query.py.
# remove this in 0.6
# removal of this has been considered, but maybe not
# see [ticket:1445]
if not clause:
if isinstance(onclause, interfaces.PropComparator):
clause = onclause.__clause_element__()
@@ -1414,7 +1415,7 @@ class Query(object):
params[_get_params[primary_key].key] = ident[i]
except IndexError:
raise sa_exc.InvalidRequestError("Could not find enough values to formulate primary key for "
"query.get(); primary key columns are %s" % ', '.join("'%s'" % c for c in q.mapper.primary_key))
"query.get(); primary key columns are %s" % ', '.join("'%s'" % c for c in mapper.primary_key))
q._params = params
if lockmode is not None:
+15
View File
@@ -165,6 +165,18 @@ nodes = fixture_table(
('id', 'parent_id', 'data')
)
composite_pk_table = fixture_table(
Table('composite_pk_table', fixture_metadata,
Column('i', Integer, primary_key=True),
Column('j', Integer, primary_key=True),
Column('k', Integer, nullable=False),
),
('i', 'j', 'k'),
(1, 2, 3),
(2, 1, 4),
(1, 1, 5),
(2, 2,6))
def _load_fixtures():
for table in fixture_metadata.sorted_tables:
@@ -203,6 +215,9 @@ class Dingaling(Base):
class Node(Base):
pass
class CompositePk(Base):
pass
class FixtureTest(_base.MappedTest):
"""A MappedTest pre-configured for fixtures.
+15 -1
View File
@@ -16,7 +16,8 @@ from test.orm import _fixtures
from test.orm._fixtures import keywords, addresses, Base, Keyword, FixtureTest, \
Dingaling, item_keywords, dingalings, User, items,\
orders, Address, users, nodes, \
order_items, Item, Order, Node
order_items, Item, Order, Node, \
composite_pk_table, CompositePk
from test.orm import _base
@@ -53,6 +54,8 @@ class QueryTest(_fixtures.FixtureTest):
)
})
mapper(CompositePk, composite_pk_table)
compile_mappers()
class RowTupleTest(QueryTest):
@@ -78,6 +81,17 @@ class GetTest(QueryTest):
u2 = s.query(User).get(7)
assert u is not u2
def test_get_composite_pk(self):
s = create_session()
assert s.query(CompositePk).get((100,100)) is None
one_two = s.query(CompositePk).get((1,2))
assert one_two.i == 1
assert one_two.j == 2
assert one_two.k == 3
q = s.query(CompositePk)
assert_raises(sa_exc.InvalidRequestError, q.get, 7)
def test_no_criterion(self):
"""test that get()/load() does not use preexisting filter/etc. criterion"""