I'm having problems with SQLAlchemy's
select_from
statement when using the core component.
I try to construct an outer join query which currently looks like:
query = select([b1.c.id, b1.c.num, n1.c.name, n1.c.num, ...] ).where(and_( ... some conditions ... ) ).select_from( ???.outerjoin( n1, and_( ... some conditions ... ) ).select_from(... more outer joins similar to the above ...)
According to the docs, the structure should look like this:
table1 = table('t1', column('a')) table2 = table('t2', column('b')) s = select([table1.ca]).\\ select_from( table1.join(table2, table1.ca==table2.cb) )
My problem is that I don't have a table1 object in this case, as the
select ...
part consists of columns and not a single table (see question marks in my query).
I've tried using
n1.outerjoin(n1...
, but that caused an exception (
Exception: (ProgrammingError) table name "n1" specified more than once
).
The above snippet is derived from a working session-based (ORM) query, which I try to convert (with limited success).
ProgrammingError: (ProgrammingError) table name "customer1" specified more than once
'SELECT customer1.id, customer.name, order1.id, order1.order_num, address1.id, address1.city \nFROM customer, customer AS customer1 LEFT OUTER JOIN "order" AS order1 ON order1.customer_id = customer1.id, customer AS customer1 LEFT OUTER JOIN address AS address1 ON customer1.id = address1.customer_id' {}
How do I go about converting this ORM query into a plain Core query?
Update:
I was able to narrow down the problem. It seems that a combination of two select_from
calls causes the problem.
customer = Table('customer', metadata, Column('id', Integer), Column('name', String(50)), ) order = Table('order', metadata, Column('id', Integer), Column('customer_id', Integer), Column('order_num', Integer), ) address = Table('address', metadata, Column('id', Integer), Column('customer_id', Integer), Column('city', String(50)), ) metadata.create_all(db) customer1 = aliased(customer, name='customer1') order1 = aliased(order, name='order1') address1 = aliased(address, name='address1') columns = [ customer1.c.id, customer.c.name, order1.c.id, order1.c.order_num, address1.c.id, address1.c.city ] query = select(columns) query = query.select_from( customer1.outerjoin( order1, and_( order1.c.customer_id==customer1.c.id, ) ) ) query = query.select_from( customer1.outerjoin( address1, and_( customer1.c.id==address1.c.customer_id ) ) ) result = connection.execute(query) for r in result.fetchall(): print r
The above code causes the following exception:
ProgrammingError: (ProgrammingError) table name "customer1" specified more than once 'SELECT customer1.id, customer.name, order1.id, order1.order_num, address1.id, address1.city \\nFROM customer, customer AS customer1 LEFT OUTER JOIN "order" AS order1 ON order1.customer_id = customer1.id, customer AS customer1 LEFT OUTER JOIN address AS address1 ON customer1.id = address1.customer_id' {}
If I was a bit more experienced in using SQLAlchemy, I would say this could be a bug...
I finally managed to solved the problem. Instead of cascading select_from
, additional joins need to be chained to the actual join. The above query would read:
query = select(columns)
query = query.select_from(
customer1.outerjoin(
order1,
and_(
order1.c.customer_id==customer1.c.id,
)
).outerjoin(
address1,
and_(
customer1.c.id==address1.c.customer_id
)
)
)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.