From 3a8e235af64e36b3b711df1f069d32359fe6c967 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Thu, 26 Jul 2007 18:25:50 +0000 Subject: [PATCH] - added a check for joining from A->B using join(), along two different m2m tables. this raises an error in 0.3 but is possible in 0.4 when aliases are used. [ticket:687] --- CHANGES | 12 +++++++++--- lib/sqlalchemy/orm/query.py | 6 ++++++ setup.py | 2 +- test/orm/query.py | 39 ++++++++++++++++++++++++++++++++++++- 4 files changed, 54 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index c4dcf46762..9d75e2dfbd 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,12 @@ +0.3.11 +- orm + - added a check for joining from A->B using join(), along two + different m2m tables. this raises an error in 0.3 but is + possible in 0.4 when aliases are used. [ticket:687] +- mssql + - added support for TIME columns (simulated using DATETIME) [ticket:679] + - index names are now quoted when dropping from reflected tables [ticket:684] + 0.3.10 - general - a new mutex that was added in 0.3.9 causes the pool_timeout @@ -19,9 +28,6 @@ - postgres - fixed max identifier length (63) [ticket:571] -- mssql - - added support for TIME columns (simulated using DATETIME) [ticket:679] - - index names are now quoted when dropping from reflected tables [ticket:684] 0.3.9 - general diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index 02deebdca9..d51fd75c38 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -614,7 +614,13 @@ class Query(object): clause = clause.join(prop.select_table, prop.get_join(mapper, primary=False)) else: clause = clause.join(prop.select_table, prop.get_join(mapper)) + elif prop.secondary is not None and prop.secondary not in currenttables: + # TODO: this check is not strong enough for different paths to the same endpoint which + # does not use secondary tables + raise exceptions.InvalidRequestError("Can't join to property '%s'; a path to this table along a different secondary table already exists. Use explicit `Alias` objects." % prop.key) + mapper = prop.mapper + return (clause, mapper) def _join_by(self, args, params, start=None): diff --git a/setup.py b/setup.py index 38b004be22..092d0d5085 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ use_setuptools() from setuptools import setup, find_packages setup(name = "SQLAlchemy", - version = "0.3.10", + version = "0.3.11", description = "Database Abstraction Library", author = "Mike Bayer", author_email = "mike_mp@zzzcomputing.com", diff --git a/test/orm/query.py b/test/orm/query.py index 22b9d8e117..872d1772e4 100644 --- a/test/orm/query.py +++ b/test/orm/query.py @@ -206,7 +206,44 @@ class JoinTest(QueryTest): result = create_session().query(User).select_from(users.join(oalias)).filter(oalias.c.description.in_("order 1", "order 2", "order 3")).join(['orders', 'items']).filter_by(id=4).all() assert [User(id=7, name='jack')] == result - +class MultiplePathTest(testbase.ORMTest): + def define_tables(self, metadata): + global t1, t2, t1t2_1, t1t2_2 + t1 = Table('t1', metadata, + Column('id', Integer, primary_key=True), + Column('data', String(30)) + ) + t2 = Table('t2', metadata, + Column('id', Integer, primary_key=True), + Column('data', String(30)) + ) + + t1t2_1 = Table('t1t2_1', metadata, + Column('t1id', Integer, ForeignKey('t1.id')), + Column('t2id', Integer, ForeignKey('t2.id')) + ) + + t1t2_2 = Table('t1t2_2', metadata, + Column('t1id', Integer, ForeignKey('t1.id')), + Column('t2id', Integer, ForeignKey('t2.id')) + ) + + def test_basic(self): + class T1(object):pass + class T2(object):pass + + mapper(T1, t1, properties={ + 't2s_1':relation(T2, secondary=t1t2_1), + 't2s_2':relation(T2, secondary=t1t2_2), + }) + mapper(T2, t2) + + try: + create_session().query(T1).join('t2s_1').filter_by(t2.c.id==5).reset_joinpoint().join('t2s_2') + assert False + except exceptions.InvalidRequestError, e: + assert str(e) == "Can't join to property 't2s_2'; a path to this table along a different secondary table already exists. Use explicit `Alias` objects." + class SynonymTest(QueryTest): keep_mappers = True keep_data = True -- 2.47.2