简体   繁体   English

在SQLAlchemy中将CTE与多个引擎一起使用时出现UnboundExecutionError

[英]UnboundExecutionError when using CTE with multiple engines in SQLAlchemy

In SQLAlchemy, when using multiple engines ( sessionmaker(binds={Base: engine}) rather than sessionmaker(bind=engine) ), it seems CTE queries (common table expressions) fail to bind properly. 在SQLAlchemy中,当使用多个引擎( sessionmaker(binds={Base: engine})而不是sessionmaker(bind=engine) )时,似乎CTE查询(公用表表达式)无法正确绑定。 Perhaps I'm doing something wrong as I'm very new to SQLAlchemy. 也许我做错了什么,因为我对SQLAlchemy很陌生。 Is there a (principled) way to make this work? 有没有一种(原则上的)方法可以完成这项工作? Perhaps I can tell SQLAlchemy what class to use for the result set? 也许我可以告诉SQLAlchemy结果集使用什么类?

The below code is directly based on the example in the Query API documentation . 以下代码直接基于Query API文档中的示例。 I've added the session set-up and simplified the CTE to just return parts. 我添加了会话设置,并将CTE简化为仅退还零件。

from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import aliased, sessionmaker

Base = declarative_base()


class Part(Base):
    __tablename__ = 'part'
    part = Column(String, primary_key=True)
    sub_part = Column(String, primary_key=True)
    quantity = Column(Integer)


engine = create_engine('sqlite:///:memory:', echo=True)

Base.metadata.create_all(engine)

Session = sessionmaker(binds={Base: engine})
session = Session()

included_parts = (session.query(Part)
                  .filter(Part.part == "our part")
                  .cte(name="included_parts", recursive=True))

incl_alias = aliased(included_parts, name="pr")
parts_alias = aliased(Part, name="p")
included_parts = included_parts.union_all(
    session.query(parts_alias)
    .filter(parts_alias.part == incl_alias.c.sub_part)
)

q = session.query(included_parts)
q.all()     # sqlalchemy.exc.UnboundExecutionError: Could not locate a
            # bind configured on SQL expression or this Session

The code runs happily if we change the Session to Session = sessionmaker(bind=engine) 如果我们将Session更改为Session = sessionmaker(bind=engine)则代码将Session = sessionmaker(bind=engine)运行

This will be fixed in SQLAlchemy 1.4 . 将在SQLAlchemy 1.4中修复 In the meantime, a workaround is to bind all relevant tables (not just Base) as suggested on that page. 同时,一种解决方法是按照该页面上的建议绑定所有相关表(不仅仅是Base)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM