summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2009-07-12 14:33:06 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2009-07-12 14:33:06 +0000
commitd99c0a9ecc4234c8bd59836bcbec2262d0a249cd (patch)
tree7e506635337df246d9a561189a9bffdec38319fe
parenteeecbb8fc66bcb62439a3539c01e4186a1698a19 (diff)
downloadsqlalchemy-d99c0a9ecc4234c8bd59836bcbec2262d0a249cd.tar.gz
- 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]
-rw-r--r--CHANGES59
-rw-r--r--lib/sqlalchemy/orm/__init__.py2
-rw-r--r--lib/sqlalchemy/orm/query.py5
-rw-r--r--test/orm/_fixtures.py15
-rw-r--r--test/orm/test_query.py16
5 files changed, 68 insertions, 29 deletions
diff --git a/CHANGES b/CHANGES
index 5323c7765..ffe4c41fc 100644
--- a/CHANGES
+++ b/CHANGES
@@ -12,6 +12,21 @@ CHANGES
[ticket:970]
- orm
+ - 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
+ the backref of a relation() has intentionally different
+ "foreign_keys" configured, both sides now need to be
+ configured explicity (if they do in fact require this setting,
+ see the next note...).
+
+ - ...the only known (and really, really rare) use case where a
+ different foreign_keys setting was used on the
+ forwards/backwards side, a composite foreign key that
+ partially points to its own columns, has been enhanced such
+ 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
@@ -20,14 +35,23 @@ CHANGES
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 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]
@@ -39,33 +63,9 @@ CHANGES
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
- the backref of a relation() has intentionally different
- "foreign_keys" configured, both sides now need to be
- configured explicity (if they do in fact require this setting,
- see the next note...).
-
- - ...the only known (and really, really rare) use case where a
- different foreign_keys setting was used on the
- forwards/backwards side, a composite foreign key that
- partially points to its own columns, has been enhanced such
- that the fk->itself aspect of the relation won't be used to
- determine relation direction.
-
- 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
diff --git a/lib/sqlalchemy/orm/__init__.py b/lib/sqlalchemy/orm/__init__.py
index 6af8dde9f..a80d17642 100644
--- a/lib/sqlalchemy/orm/__init__.py
+++ b/lib/sqlalchemy/orm/__init__.py
@@ -81,11 +81,13 @@ __all__ = (
'eagerload',
'eagerload_all',
'extension',
+ 'join',
'lazyload',
'mapper',
'noload',
'object_mapper',
'object_session',
+ 'outerjoin',
'polymorphic_union',
'reconstructor',
'relation',
diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py
index dee57bbc1..c0eb3b02a 100644
--- a/lib/sqlalchemy/orm/query.py
+++ b/lib/sqlalchemy/orm/query.py
@@ -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:
diff --git a/test/orm/_fixtures.py b/test/orm/_fixtures.py
index 14709ec43..931d8cadf 100644
--- a/test/orm/_fixtures.py
+++ b/test/orm/_fixtures.py
@@ -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.
diff --git a/test/orm/test_query.py b/test/orm/test_query.py
index de1f3be41..b079e35f2 100644
--- a/test/orm/test_query.py
+++ b/test/orm/test_query.py
@@ -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"""