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. Perhaps I'm doing something wrong as I'm very new to SQLAlchemy. Is there a (principled) way to make this work? Perhaps I can tell SQLAlchemy what class to use for the result set?
The below code is directly based on the example in the Query API documentation . I've added the session set-up and simplified the CTE to just return parts.
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)
This will be fixed in SQLAlchemy 1.4 . In the meantime, a workaround is to bind all relevant tables (not just Base) as suggested on that page.
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.