📅  最后修改于: 2020-11-27 07:52:08             🧑  作者: Mango
现在我们有两个表,我们将看到如何在两个表上同时创建查询。为了在Customer和Invoice之间构造一个简单的隐式联接,我们可以使用Query.filter()将它们的相关列等同在一起。下面,我们使用此方法立即加载“客户”和“发票”实体-
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind = engine)
session = Session()
for c, i in session.query(Customer, Invoice).filter(Customer.id == Invoice.custid).all():
print ("ID: {} Name: {} Invoice No: {} Amount: {}".format(c.id,c.name, i.invno, i.amount))
SQLAlchemy发出的SQL表达式如下-
SELECT customers.id
AS customers_id, customers.name
AS customers_name, customers.address
AS customers_address, customers.email
AS customers_email, invoices.id
AS invoices_id, invoices.custid
AS invoices_custid, invoices.invno
AS invoices_invno, invoices.amount
AS invoices_amount
FROM customers, invoices
WHERE customers.id = invoices.custid
以上代码行的结果如下-
ID: 2 Name: Gopal Krishna Invoice No: 10 Amount: 15000
ID: 2 Name: Gopal Krishna Invoice No: 14 Amount: 3850
ID: 3 Name: Govind Pant Invoice No: 3 Amount: 10000
ID: 3 Name: Govind Pant Invoice No: 4 Amount: 5000
ID: 4 Name: Govind Kala Invoice No: 7 Amount: 12000
ID: 4 Name: Govind Kala Invoice No: 8 Amount: 8500
ID: 5 Name: Abdul Rahman Invoice No: 9 Amount: 15000
ID: 5 Name: Abdul Rahman Invoice No: 11 Amount: 6000
实际的SQL JOIN语法可以使用Query.join()方法轻松实现,如下所示:
session.query(Customer).join(Invoice).filter(Invoice.amount == 8500).all()
连接的SQL表达式将显示在控制台上-
SELECT customers.id
AS customers_id, customers.name
AS customers_name, customers.address
AS customers_address, customers.email
AS customers_email
FROM customers JOIN invoices ON customers.id = invoices.custid
WHERE invoices.amount = ?
我们可以使用for循环遍历结果-
result = session.query(Customer).join(Invoice).filter(Invoice.amount == 8500)
for row in result:
for inv in row.invoices:
print (row.id, row.name, inv.invno, inv.amount)
将8500作为绑定参数,显示以下输出-
4 Govind Kala 8 8500
Query.join()知道如何在这些表之间进行联接,因为它们之间只有一个外键。如果没有外键或更多外键,则使用以下形式之一时,Query.join()会更好地工作-
query.join(Invoice, id == Address.custid) | explicit condition |
query.join(Customer.invoices) | specify relationship from left to right |
query.join(Invoice, Customer.invoices) | same, with explicit target |
query.join(‘invoices’) | same, using a string |
类似地,outerjoin()函数可用于实现左外部联接。
query.outerjoin(Customer.invoices)
subquery()方法产生一个SQL表达式,表示嵌入在别名中的SELECT语句。
from sqlalchemy.sql import func
stmt = session.query(
Invoice.custid, func.count('*').label('invoice_count')
).group_by(Invoice.custid).subquery()
stmt对象将包含如下SQL语句-
SELECT invoices.custid, count(:count_1) AS invoice_count FROM invoices GROUP BY invoices.custid
有了语句后,它的行为就像一个Table构造。可以通过名为c的属性访问语句上的列,如以下代码所示-
for u, count in session.query(Customer, stmt.c.invoice_count).outerjoin(stmt, Customer.id == stmt.c.custid).order_by(Customer.id):
print(u.name, count)
上面的for循环显示按名称的发票计数,如下所示-
Arjun Pandit None
Gopal Krishna 2
Govind Pant 2
Govind Kala 2
Abdul Rahman 2