New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CTE alias forgotten if used in two different CTEs #4204
Comments
Michael Bayer (@zzzeek) wrote: fixing this I found myself inserting a large block of code in a place that is frequently encountered by existing tests. it seemed likely that the code to render the new "x AS y" was going to conflict with some other assumptions. But it looks like in all those cases the tests already hit, we are using a cte() and not a cte().alias(). That is, if I take all those tests and make a new one with alias(), it fails to write the correct SQL in just the same way as here. TL;DR you caught a big fish |
Michael Bayer (@zzzeek) wrote: and a chunk of those tests are all called "test_recursive_union_no_alias_", and there's no "test_recursive_union_alias_" test :) even have the names ready. |
Michael Bayer (@zzzeek) wrote: |
Michael Bayer (@zzzeek) wrote: Check existing CTE for an alias name when rendering FROM clause Fixed bug in CTE rendering where a :class: Change-Id: If8cff27a2f4faa5eceb59aa86398db6edb3b9e72 → 5f60dc6 |
Changes by Michael Bayer (@zzzeek):
|
Frazer McLean (@RazerM) wrote: Thanks for the effort! |
Michael Bayer (@zzzeek) wrote: Check existing CTE for an alias name when rendering FROM clause Fixed bug in CTE rendering where a :class: Change-Id: If8cff27a2f4faa5eceb59aa86398db6edb3b9e72 → 3cfa074 |
Sebastian Bank (@xflr6) wrote: Not sure if I was using it wrong, but doing import sqlalchemy as sa
import sqlalchemy.ext.declarative
engine = sa.create_engine('sqlite://')
class Node(sa.ext.declarative.declarative_base()):
__tablename__ = 'node'
id = sa.Column(sa.Integer, primary_key=True)
parent_id = sa.Column(sa.ForeignKey('node.id'))
@classmethod
def tree(cls):
child, parent = (sa.orm.aliased(cls, name=n) for n in ('child', 'parent'))
tree_1 = sa.select([
child.id.label('child_id'),
child.parent_id.label('parent_id'),
]).where(child.parent_id != None)\
.cte(recursive=True)\
.alias('tree')
tree_2 = sa.select([tree_1.c.child_id, parent.parent_id])\
.select_from(tree_1.join(parent, parent.id == tree_1.c.parent_id))\
.where(parent.parent_id != None)
return tree_1.union_all(tree_2)
Node.metadata.create_all(engine)
tree = Node.tree()
query = sa.select([tree.c.child_id, tree.c.parent_id], bind=engine)
print(query)
query.execute() Before:
After (
|
Michael Bayer (@zzzeek) wrote: OK, so you are doing it differently than the documentation states at http://docs.sqlalchemy.org/en/latest/core/selectable.html?highlight=cte#sqlalchemy.sql.expression.Select.cte - the .union() is called against the CTE() object, not the alias(). Can you work with it that way for now? |
Sebastian Bank (@xflr6) wrote: Thanks Mike (just to make sure: apart from doing I can adapt, just wanted to make sure you are informed. Maybe this can be noted in the migration notes, |
Michael Bayer (@zzzeek) wrote: I couldn't find any test that seemed to depend on the way it was previously so let me see if i can make it work again. |
Michael Bayer (@zzzeek) wrote: found it |
Changes by Michael Bayer (@zzzeek):
|
Changes by Michael Bayer (@zzzeek):
|
Changes by Michael Bayer (@zzzeek):
|
Michael Bayer (@zzzeek) wrote: alrighty https://gerrit.sqlalchemy.org/#/q/Iaa63d65ad2b90c8693f9953fbb32dbb10c73a037 |
Michael Bayer (@zzzeek) wrote: Track if we're rendering within the CTE recursively Fixed a regression that occurred from the previous fix to 🎫 Change-Id: Iaa63d65ad2b90c8693f9953fbb32dbb10c73a037 → ef2859b |
Michael Bayer (@zzzeek) wrote: Track if we're rendering within the CTE recursively Fixed a regression that occurred from the previous fix to 🎫 Change-Id: Iaa63d65ad2b90c8693f9953fbb32dbb10c73a037 → e05f91e |
Changes by Michael Bayer (@zzzeek):
|
Migrated issue, originally created by Frazer McLean (@RazerM)
If we have a CTE named
cte1
aliased asaa
, the generated SQL is wrong when the alias is used in CTEscte2
andcte3
.Output (formatted)
The problem is that
cte3
hasJOIN aa
instead ofJOIN cte1 AS aa
.I initially came across this using the PostgreSQL dialect (with psycopg2), but the dialect-independent test case above also demonstrates the problem.
It may be that using a CTE alias like this isn't supported but if
cte1
was aliased as an existing table name,cte3
would be joining to that table instead ofcte1
.I'm using SQLAlchemy v1.2.4.
The text was updated successfully, but these errors were encountered: