我有三张桌子。这些约束由ForeignKey
约束,因此sqlalchemy知道如何加入它们。
我想从所有三个表中选择列:
select([a.c.x, b.c.x, c.c.x], a.c.a.between(10,20), [join(a, c), join(a, b)])
这会生成损坏的SQL:
SELECT a.x, b.x, c.x
FROM
a JOIN b ON a.b_id == b.id,
a JOIN c ON a.c_id == c.id
WHERE
a.a BETWEEN 10 AND 20;
可以看出,表a
在FROM
子句中两次!
如何使用sqlalchemy在select()语句中加入三个表?
答案 0 :(得分:1)
简短的回答是
select([a.c.x, b.c.x, c.c.x]).\
select_from(a.join(b).join(c)).\
where(between(a.c.a, 5, 15))
如果有人想要在这里试试,那就是整个事情。
import sqlalchemy
from sqlalchemy import Table, Column, Integer, String, Sequence,\
ForeignKey, select, between
meta = sqlalchemy.MetaData()
url = 'sqlite:///:memory:'
engine = sqlalchemy.create_engine(url)
a = Table(
'a', meta,
Column('id', Integer, Sequence('a_id_seq'), primary_key=True),
Column('age', Integer),
Column('name', String(20))
)
b = Table(
'b', meta,
Column('a_id', Integer, ForeignKey("a.id")),
Column('value', String(20))
)
c = Table(
'c', meta,
Column('a_id', Integer, ForeignKey("a.id")),
Column('title', String(20))
)
# Create tables
meta.create_all(engine)
# Fill with dummy data
def add_data(age, name, value, title):
q = a.insert().values({a.c.age: age, a.c.name: name})
res = engine.execute(q)
a_id = res.inserted_primary_key[0]
q = b.insert().values({b.c.a_id: a_id, b.c.value: value})
engine.execute(q)
q = c.insert().values({c.c.a_id: a_id, c.c.title: title})
engine.execute(q)
add_data(12, 'Foo', 'Bar', 'Baz')
add_data(17, '111', '222', '333')
q = select([a.c.name, b.c.value, c.c.title]).\
select_from(a.join(b).join(c)).\
where(between(a.c.age, 5, 15))
print(str(q))
# SELECT a.name, b.value, c.title
# FROM a JOIN b ON a.id = b.a_id JOIN c ON a.id = c.a_id
# WHERE a.age BETWEEN :age_1 AND :age_2
res = engine.execute(q)
for row in res.fetchall():
print(row)
# ('Foo', 'Bar', 'Baz')
更新了答案,thx为评论Will!
答案 1 :(得分:0)
给下面一个去吧。
SELECT a.x, b.x, c.x
FROM *TABLENAME* a
JOIN *TABLENAME* b
ON a.id = b.id
JOIN *TABLENAME* c
ON a.id = c.id
WHERE
a.a BETWEEN 10 AND 20