roc*_*eza 4 python sql sqlalchemy
我试图从有关将模型映射到任意表的文档中复制代码,但是我收到以下错误:
sqlalchemy.exc.InvalidRequestError: When mapping against a select() construct, map against an alias() of the construct instead.This because several databases don't allow a SELECT from a subquery that does not have an alias.
Run Code Online (Sandbox Code Playgroud)
这是我实现代码示例的方式.
from sqlalchemy import (
select, func,
Table, Column,
Integer, ForeignKey,
MetaData,
)
from sqlalchemy.ext.declarative import declarative_base
metadata = MetaData()
Base = declarative_base()
customers = Table('customer', metadata,
Column('id', Integer, primary_key=True),
)
orders = Table('order', metadata,
Column('id', Integer, primary_key=True),
Column('price', Integer),
Column('customer_id', Integer, ForeignKey('customer.id')),
)
subq = select([
func.count(orders.c.id).label('order_count'),
func.max(orders.c.price).label('highest_order'),
orders.c.customer_id
]).group_by(orders.c.customer_id).alias()
customer_select = select([customers,subq]).\
where(customers.c.id==subq.c.customer_id)
class Customer(Base):
__table__ = customer_select
Run Code Online (Sandbox Code Playgroud)
我可以通过使用以下内容来完成这项工作:
class Customer(Base):
__table__ = customer_select.alias()
Run Code Online (Sandbox Code Playgroud)
不幸的是,这会在子选择中创建所有查询,这非常慢.
有没有办法将模型映射到任意选择?这是文档错误 - 来自文档的代码示例对我不起作用(在sqlalchemy == 0.8.0b2或0.7.10中)
如果一个子查询变得"非常慢",这可能意味着你正在使用MySQL,正如我在其他地方所指出的那样,它具有非常不可接受的子查询性能.
基本上,select的映射需要该语句被括号,因此它的内部构造不会向外泄漏到使用它的上下文中,因此select()构造本身不需要变异.
考虑一下你是否要像这样映射到SELECT:
SELECT id, name FROM table WHERE id = 5
Run Code Online (Sandbox Code Playgroud)
现在假设你要从这个映射中选择:
ma = aliased(Mapping)
query(Mapping).join(ma, Mapping.name == ma.name)
Run Code Online (Sandbox Code Playgroud)
如果没有你的映射选择是一个别名,SQLAlchemy必须修改你的select(),这意味着它必须深入研究它并完全理解它的几何,这可能非常复杂(考虑它是否有LIMIT,ORDER BY,GROUP BY) ,聚合等):
SELECT id, name FROM table
JOIN (SELECT id, name FROM table) as anon_1 ON table.name = anon_1.name
WHERE table.id = 5
Run Code Online (Sandbox Code Playgroud)
然而,当它自包含时,SQLAlchemy可以保持对select()的结构一无所知,并像使用任何其他表一样使用它:
SELECT id, name FROM (SELECT id, name FROM table WHERE id = 5) as a1
JOIN (SELECT id, name FROM table WHERE id = 5) as a2 ON a1.name = a2.name
Run Code Online (Sandbox Code Playgroud)
实际上,映射到SELECT语句是一种罕见的用例,因为Query构造通常足够灵活,可以执行您需要的任何模式.SQLAlchemy的早期版本以mapper()主要查询对象为特色,在内部我们确实mapper()以这种方式利用了它的灵活性(特别是在连接继承中),但是不需要经常使用显式方法.
这是文档错误 - 来自文档的代码示例对我不起作用(在sqlalchemy == 0.8.0b2或0.7.10中)
感谢您指出了这一点.我已经纠正了例子,还增加了一个巨大的音符总体劝阻的做法,因为它没有大量的使用(我知道这是因为我从来没有使用它).
| 归档时间: |
|
| 查看次数: |
1883 次 |
| 最近记录: |