joinedload 和 load_only 但有过滤
joinedload and load_only but with filtering
我有两个具有简单 FK 关系的模型,Stock 和 Restriction(Restriction.stock_id FK 到 Stock)。
class Restriction(Model):
__tablename__ = "restrictions"
id = db.Column(db.Integer, primary_key=True)
stock_id = FK("stocks.id", nullable=True)
name = db.Column(db.String(50), nullable=False)
class Stock(Model):
__tablename__ = "stocks"
id = db.Column(db.Integer, primary_key=True)
ticker = db.Column(db.String(50), nullable=False, index=True)
我想检索 Restriction 对象和相关的 Stock 但只有 Stock 的代码(这里省略了其他字段)。我可以简单地这样做:
from sqlalchemy.orm import *
my_query = Restriction.query.options(
joinedload(Restriction.stock).load_only(Stock.ticker)
)
r = my_query.first()
我得到了所有限制栏,只有上面的股票代码。我可以在 SQL 查询 运行 中看到这个,我也可以访问 r.stock.ticker
并且看不到新查询 运行 因为它是急切加载的。
问题是我现在无法过滤股票,SQL如果我过滤 my_query.filter(Stock.ticker == 'GME')
,Alchemy 会添加另一个 FROM 子句。这意味着有一个叉积,这不是我想要的。
另一方面,我无法使用 join
从关系中加载选定的列。即
Restriction.query.join(Restriction.stock).options(load_only(Restriction.stock))
似乎不适用于关系 属性。我怎样才能拥有一个过滤器并让它从关系 table?
中加载选定的列
SQL我要运行是:
SELECT restrictions.*, stocks.ticker
FROM restrictions LEFT OUTER JOIN stocks ON stocks.id = restrictions.stock_id
WHERE stocks.ticker = 'GME'
而且我想取回一个 Restriction 对象及其股票和股票代码。这可能吗?
joinedload
基本上不应该和filter
一起使用。您可能需要选择 contains_eager
选项。
from sqlalchemy.orm import *
my_query = Restriction.query.join(Restriction.stock).options(
contains_eager(Restriction.stock).load_only(Stock.ticker)
).filter(Stock.ticker == 'GME')
r = my_query.first()
因为您使用 stock_id
加入,它在结果中也会作为 Stock.id
在 Stock.ticker
旁边。但其他字段将根据您的意愿省略。
我最近写了简短的 post 如果你有兴趣的话:https://jorzel.hashnode.dev/an-orm-can-bite-you
我有两个具有简单 FK 关系的模型,Stock 和 Restriction(Restriction.stock_id FK 到 Stock)。
class Restriction(Model):
__tablename__ = "restrictions"
id = db.Column(db.Integer, primary_key=True)
stock_id = FK("stocks.id", nullable=True)
name = db.Column(db.String(50), nullable=False)
class Stock(Model):
__tablename__ = "stocks"
id = db.Column(db.Integer, primary_key=True)
ticker = db.Column(db.String(50), nullable=False, index=True)
我想检索 Restriction 对象和相关的 Stock 但只有 Stock 的代码(这里省略了其他字段)。我可以简单地这样做:
from sqlalchemy.orm import *
my_query = Restriction.query.options(
joinedload(Restriction.stock).load_only(Stock.ticker)
)
r = my_query.first()
我得到了所有限制栏,只有上面的股票代码。我可以在 SQL 查询 运行 中看到这个,我也可以访问 r.stock.ticker
并且看不到新查询 运行 因为它是急切加载的。
问题是我现在无法过滤股票,SQL如果我过滤 my_query.filter(Stock.ticker == 'GME')
,Alchemy 会添加另一个 FROM 子句。这意味着有一个叉积,这不是我想要的。
另一方面,我无法使用 join
从关系中加载选定的列。即
Restriction.query.join(Restriction.stock).options(load_only(Restriction.stock))
似乎不适用于关系 属性。我怎样才能拥有一个过滤器并让它从关系 table?
中加载选定的列SQL我要运行是:
SELECT restrictions.*, stocks.ticker
FROM restrictions LEFT OUTER JOIN stocks ON stocks.id = restrictions.stock_id
WHERE stocks.ticker = 'GME'
而且我想取回一个 Restriction 对象及其股票和股票代码。这可能吗?
joinedload
基本上不应该和filter
一起使用。您可能需要选择 contains_eager
选项。
from sqlalchemy.orm import *
my_query = Restriction.query.join(Restriction.stock).options(
contains_eager(Restriction.stock).load_only(Stock.ticker)
).filter(Stock.ticker == 'GME')
r = my_query.first()
因为您使用 stock_id
加入,它在结果中也会作为 Stock.id
在 Stock.ticker
旁边。但其他字段将根据您的意愿省略。
我最近写了简短的 post 如果你有兴趣的话:https://jorzel.hashnode.dev/an-orm-can-bite-you