Buglette with annotated join condition
Here's the crux (full test script attached below).
I have an explicitly annotated join condition. One of the columns in the ON clause is not having its name qualified with its table.
class TableTwo(Base):
...
x = Column(Integer)
r = relationship(TableOne, primaryjoin=remote(TableOne.x)==foreign(x))
print sess.query(TableTwo).join('r')
>>> SELECT ... FROM Two JOIN One ON One.x = x
Executing this query results in an "ambiguous column name" operational error.
This behavior seems to pertain to 0.8.2, rel_0_8 and master (atm).
Specifying the join condition as a string (so that it get evalled later) works correctly.
Using the {{{foreign_keys}}} arg instead of the {{{foreign()}}} annotation work correctly.
Comments (6)
-
repo owner -
repo owner well I guess we can do this, seems to be an approach we're taking already:
diff --git a/lib/sqlalchemy/sql/elements.py b/lib/sqlalchemy/sql/elements.py index 17fb406..4263e82 100644 --- a/lib/sqlalchemy/sql/elements.py +++ b/lib/sqlalchemy/sql/elements.py @@ -2355,7 +2355,7 @@ class AnnotatedColumnElement(Annotated): def __init__(self, element, values): Annotated.__init__(self, element, values) ColumnElement.comparator._reset(self) - for attr in ('name', 'key'): + for attr in ('name', 'key', 'table'): if self.__dict__.get(attr, False) is None: self.__dict__.pop(attr) @@ -2375,6 +2375,10 @@ class AnnotatedColumnElement(Annotated): return self._Annotated__element.key @util.memoized_property + def table(self): + return self._Annotated__element.table + + @util.memoized_property def info(self): return self._Annotated__element.info
-
repo owner - marked as critical
OK tests pass with that I can go with that.
-
reporter Thanks Mike.
I've tried the above patch on rel_0_8. It does appear to fix the problem (and the tests pass here too).
(For the record, here's your patch adapted for rel_0_8. It's on util.py rather than elements.py.)
diff --git a/lib/sqlalchemy/sql/util.py b/lib/sqlalchemy/sql/util.py index 61730f1..2799d8c 100644 --- a/lib/sqlalchemy/sql/util.py +++ b/lib/sqlalchemy/sql/util.py @@ -497,7 +497,7 @@ class Annotated(object): class AnnotatedColumnElement(Annotated): def __init__(self, element, values): Annotated.__init__(self, element, values) - for attr in ('name', 'key'): + for attr in ('name', 'key', 'table'): if self.__dict__.get(attr, False) is None: self.__dict__.pop(attr) @@ -512,6 +512,10 @@ class AnnotatedColumnElement(Annotated): return self._Annotated__element.key @util.memoized_property + def table(self): + return self._Annotated__element.table + + @util.memoized_property def info(self): return self._Annotated__element.info
-
repo owner - changed status to resolved
-
repo owner - removed milestone
Removing milestone: 0.8.xx (automated comment)
- Log in to comment
yeah not sure how to handle this, annotation() makes a copy of the Column, and in this case it's copying it before it gets a table assigned.
If you use this patch:
it raises an error, but this isn't great.
the workaround is to use a string,
primaryjoin="(remote(TableOne.x) == foreign(TableTwo.x))"
.i might have realized this issue a while back but i dont have a good idea how to deal with it.