Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 带有连接的Django查询_Python_Mysql_Django_Join_Sqlalchemy - Fatal编程技术网

Python 带有连接的Django查询

Python 带有连接的Django查询,python,mysql,django,join,sqlalchemy,Python,Mysql,Django,Join,Sqlalchemy,我需要编写一个复杂的查询,它从一堆表中检索大量数据。基本上我需要找到模型的所有实例 顾客 付款 发票 关系以特定方式相交的地方。在SqlAlchemy中,我可以做如下的事情 for c, p, i in session.query(Customer, Payment, Invoice).\ filter(User.id==Payment.customer_id).\ filter(Invoice.id==Payment.invoice_id).\

我需要编写一个复杂的查询,它从一堆表中检索大量数据。基本上我需要找到模型的所有实例

  • 顾客
  • 付款
  • 发票
关系以特定方式相交的地方。在SqlAlchemy中,我可以做如下的事情

for c, p, i in session.query(Customer, Payment, Invoice).\
        filter(User.id==Payment.customer_id).\
        filter(Invoice.id==Payment.invoice_id).\
        filter(Payment.date==...).\
        filter(Customer.some_property==...)
        all():
    # Do stuff ...
customers = Customer.objects.filter(...).prefetch_related(
    'payments', 'payments__invoices'
)
这将允许我设置几个约束并一次检索所有约束。在Django,我现在做了一些愚蠢的事情,比如

customers = Customer.objects.filter(...)
payments = Payment.objects.filter(customer=customer)
invoices = Invoice.objects.filter(customer=customer, payment_set=payments)
现在,我们已经有了三个不同的查询(为了保持简单,省略了一些细节)。我能把它减少到一个吗?好吧,我本来可以这样做的

for c, p, i in session.query(Customer, Payment, Invoice).\
        filter(User.id==Payment.customer_id).\
        filter(Invoice.id==Payment.invoice_id).\
        filter(Payment.date==...).\
        filter(Customer.some_property==...)
        all():
    # Do stuff ...
customers = Customer.objects.filter(...).prefetch_related(
    'payments', 'payments__invoices'
)

但现在我必须遍历一个疯狂的数据树,而不是像SqlAlchemy那样将所有数据整齐地排成一行。Django有没有办法做那样的事?还是我必须直接访问自定义SQL?

在阅读了不同的解决方案后,我决定在Django模型的基础上使用SqlAlchemy。有些人试图用SqlAlchemy完全取代Django ORM,但这几乎完全违背了使用Django的目的,因为大多数框架都依赖于ORM

相反,我使用SqlAlchemy simple查询Django ORM定义的表。我遵循与此类似的食谱

# Setup sqlalchemy bindings
import sqlalchemy as s
from sqlalchemy.orm import sessionmaker
engine = s.create_engine('postgresql://<user>:<password>@<host>:<port>/<db_name>')
# Automatically read the database tables and create metadata
meta = s.MetaData()
meta.reflect(bind=engine)
Session = sessionmaker(bind=engine)
# Create a session, which can query the tables
session = Session()

# Build table instances without hardcoding tablenames
s_payment = meta.tables[models.Payment()._meta.db_table]
s_allocation = meta.tables[models.Allocation()._meta.db_table]
s_customer = meta.tables[models.Customer()._meta.db_table]
s_invoice = meta.tables[models.Invoice()._meta.db_table]

report = session.query(s_payment.c.amount, ...).all()
#设置sqlalchemy绑定
将sqlalchemy导入为s
从sqlalchemy.orm导入sessionmaker
engine=s.create_engine('postgresql://:@://'))
#自动读取数据库表并创建元数据
meta=s.MetaData()
meta.reflect(绑定=引擎)
会话=会话生成器(绑定=引擎)
#创建可以查询表的会话
会话=会话()
#生成不硬编码表名的表实例
s_payment=meta.tables[models.payment()。_meta.db_table]
s_allocation=meta.tables[models.allocation()。_meta.db_table]
s_customer=meta.tables[models.customer()。_meta.db_table]
s_invoice=meta.tables[models.invoice()。_meta.db_table]
报告=session.query(s_payment.c.amount…).all()
这个方法还有一些改进的余地,例如,创建一个Django模型的空实例以查找它们的表名不是很优雅,但是,通过几行代码,我可以在不影响Django ORM层的情况下获得SqlAlchemy的全部灵活性。这意味着双方可以幸福地生活在一起


需要注意的是,SqlAlchemy不会使用与Django ORM相同的连接,这意味着如果在同一上下文中使用这两种方法,则对事物的看法可能不一致。不过,这对我来说不是问题,因为我只想从数据库中读取一组数据。

一些数据库专家说,如果您的查询跨越两个以上的表,那么您应该转到SQL,而不是使用ORM。就我个人而言,我从未对这两个选项进行过基准测试,但你可以尝试这样做。我不确定我是否信任奥尔杰米。它基本上没有文档化(我想它很简单,没有什么好说的),而且它似乎在python3中被模糊的错误消息打断了。不过谢谢:)