- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
例如,我有 Parcel
模型,其中有 sender
和 receiver
,两者都是 Subject
。我正在尝试从特定发件人处获取包裹。我不想使用 Parcel.sender.has()
,因为性能原因,我的真实表太大了。
来自docs :
Because has() uses a correlated subquery, its performance is not nearly as good when compared against large target tables as that of using a join.
这是一个完整的粘贴并运行示例:
from sqlalchemy import create_engine, Column, Integer, Text, ForeignKey
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy.ext.declarative.api import declarative_base
from sqlalchemy.orm.util import aliased
engine = create_engine('sqlite://')
Session = sessionmaker(bind=engine)
s = Session()
Base = declarative_base()
class Subject(Base):
__tablename__ = 'subject'
id = Column(Integer, primary_key=True)
name = Column(Text)
class Parcel(Base):
__tablename__ = 'parcel'
id = Column(Integer, primary_key=True)
sender_id = Column(Integer, ForeignKey('subject.id'))
receiver_id = Column(Integer, ForeignKey('subject.id'))
sender = relationship('Subject', foreign_keys=[sender_id], uselist=False, lazy='joined')
receiver = relationship('Subject', foreign_keys=[receiver_id], uselist=False, lazy='joined')
def __repr__(self):
return '<Parcel #{id} {s} -> {r}>'.format(id=self.id, s=self.sender.name, r=self.receiver.name)
# filling database
Base.metadata.create_all(engine)
p = Parcel()
p.sender, p.receiver = Subject(name='Bob'), Subject(name='Alice')
s.add(p)
s.flush()
#
# Method #1 - using `has` method - working but slow
print(s.query(Parcel).filter(Parcel.sender.has(name='Bob')).all())
因此,我尝试按别名关系加入和过滤,这引发了错误:
#
# Method #2 - using aliased joining - doesn't work
# I'm getting next error:
#
# sqlalchemy.exc.InvalidRequestError: Could not find a FROM clause to join from.
# Tried joining to <AliasedClass at 0x7f24b7adef98; Subject>, but got:
# Can't determine join between 'parcel' and '%(139795676758928 subject)s';
# tables have more than one foreign key constraint relationship between them.
# Please specify the 'onclause' of this join explicitly.
#
sender = aliased(Parcel.sender)
print(s.query(Parcel).join(sender).filter(sender.name == 'Bob').all())
我发现,如果我指定带有连接条件而不是关系的模型,它就会起作用。但最终的 SQL 查询不是我所期望的:
print(
s.query(Parcel)\
.join(Subject, Parcel.sender_id == Subject.id)\
.filter(Subject.name == 'Bob')
)
生成下一个 SQL 查询:
SELECT parcel.id AS parcel_id,
parcel.sender_id AS parcel_sender_id,
parcel.receiver_id AS parcel_receiver_id,
subject_1.id AS subject_1_id,
subject_1.name AS subject_1_name,
subject_2.id AS subject_2_id,
subject_2.name AS subject_2_name
FROM parcel
JOIN subject ON parcel.sender_id = subject.id
LEFT OUTER JOIN subject AS subject_1 ON subject_1.id = parcel.sender_id
LEFT OUTER JOIN subject AS subject_2 ON subject_2.id = parcel.receiver_id
WHERE subject.name = ?
在这里您可以看到 subject
表被连接了三次而不是两次。这是因为sender
和receiver
关系都配置为加载连接。第三个连接是我正在过滤的主题。
我希望最终的查询将如下所示:
SELECT parcel.id AS parcel_id,
parcel.sender_id AS parcel_sender_id,
parcel.receiver_id AS parcel_receiver_id,
subject_1.id AS subject_1_id,
subject_1.name AS subject_1_name,
subject_2.id AS subject_2_id,
subject_2.name AS subject_2_name
FROM parcel
LEFT OUTER JOIN subject AS subject_1 ON subject_1.id = parcel.sender_id
LEFT OUTER JOIN subject AS subject_2 ON subject_2.id = parcel.receiver_id
WHERE subject_1.name = ?
我相信通过多个引用关系进行过滤不应该那么不清楚,并且有更好、更清晰的方法来做到这一点。请帮我找到它。
最佳答案
您已将其配置为发送者
和接收者
将始终通过连接加载。
当您实际上需要通过连接同时加载它们时,您可以更改它并手动执行joinedload
。
如果您希望保留定义不变,您可以“帮助”SQLAlchemy 并指出查询已经拥有用于此比较的所有数据,并且不需要额外的联接。为此,使用 contains_eager
选项。
修改后的查询:
q = (s.query(Parcel)
.join(Parcel.sender)
.options(contains_eager(Parcel.sender))
.filter(Subject.name == 'Bob'))
它生成的 SQL:
SELECT subject.id AS subject_id,
subject.name AS subject_name,
parcel.id AS parcel_id,
parcel.sender_id AS parcel_sender_id,
parcel.receiver_id AS parcel_receiver_id,
subject_1.id AS subject_1_id,
subject_1.name AS subject_1_name
FROM parcel
JOIN subject ON subject.id = parcel.sender_id
LEFT OUTER JOIN subject AS subject_1 ON subject_1.id = parcel.receiver_id
WHERE subject.name = ?
关于python - sqlalchemy 按具有多个关系引用的模型进行过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47548175/
下面的说法正确吗? “人最好的 friend 是狗。” public class Mann { private BestFriend dog; //etc } 最佳答案 我想说这样
我一直在 documentation 中查看 Laravel 4 中的关系我正在尝试解决以下问题。 我的数据库中有一个名为“事件”的表。该表具有各种字段,主要包含与其他表相关的 ID。例如,我有一个“
我的表具有如下关系: 我有相互链接的级联下拉框,即当您选择国家/地区时,该国家/地区下的区域将加载到区域下拉列表中。但现在我想将下拉菜单更改为基于 Ajax 的自动完成文本框。 我的问题是,我应该有多
我正在尝试弄清楚如何构建这个数据库。我之前用过Apple的核心数据就好了,现在我只是在做一个需要MySQL的不同项目。我是 MySQL 的新手,所以请放轻松。 :) 对于这个例子,假设我有三个表,Us
MongoDB 的关系表示多个文档之间在逻辑上的相互联系。 文档间可以通过嵌入和引用来建立联系。 MongoDB 中的关系可以是: 1:1 (1对1) 1: N (1对多)
您能解释一下 SQL 中“范围”和“分配单元”之间的区别或关系吗? 最佳答案 分配单元基本上只是一组页面。它可以很小(一页)或很大(很多页)。它在 sys.allocation_units 中有一个元
我有一个表 geoLocations,其中包含两列纬度和经度。还有第二个表(让我们将其命名为城市),其中包含每对唯一的纬度和经度对应的城市。 如何使用 PowerPivot 为这种关系建模?创建两个单
我想用 SQLDelight 建模关系,尤其是 一对多关系。 我有 2 张 table :recipe和 ingredient .为简单起见,它们看起来像这样: CREATE TABLE recipe
我是 Neo4J 新手,我有一个带有源和目标 IP 的简单 CSV。我想在具有相同标签的节点之间创建关系。 类似于... source_ip >> ALERTS >> dest_ip,或者相反。 "d
我正在创建一个类图,但我想知道下面显示的两个类之间是否会有任何关联 - 据我了解,对于关联,ClassA 必须有一个 ClassB 的实例,在这种情况下没有但是,它确实需要知道 ClassB 的一个变
是否可以显示其他属性,即“hasTopping”等? 如何在 OWLViz 中做到这一点? 最佳答案 OWLViz 仅 显示类层次结构(断言和推断的类层次结构)。仅使用“is-a”关系进行描述。 OW
public class MainClass { ArrayList mans = new ArrayList(); // I'm filling in this arraylist,
我想知道“多对二”的关系。 child 可以与两个 parent 中的任何一个联系,但不能同时与两个 parent 联系。有什么办法可以加强这一点吗?我也想防止 child 重复条目。 一个真实的例子
我有一个已经创建的Grails插件,旨在支持许多应用程序。该插件具有一个Employee域对象。问题在于,当在主应用程序中使用该应用程序中的域对象时,需要将其引用回Employee对象。因此,我的主应
我有一个类(class)表、类(class)hasMany部分和部分hasMany讲座以及讲座hasMany评论。如果我有评论 ID 并且想知道其类(class)名称,我应该如何在 LectureCo
我有一个模型团队,包含 ID 和名称。所有可能的团队都会被存储。 我的模型游戏有两列 team_1 和 team_2..我需要哪种关系? 我已经测试了很多,但它只适用于一列.. 最佳答案 也许你可以试
我读了很多关于 ICE 或 Corba 等技术中使用的仆人和对象的文章。有很多资源我可以读到这样的东西: 一个仆人可以处理多个对象(为了节省资源)。 一个对象可以由多个仆人处理(为了可靠性)。 有人可
嗨, 我有一个令人沮丧的问题,我在这方面有点生疏。我有两个这样的类(class): class A{ int i; String j ; //Getters and setters} class B
class Employee { private String name; void setName(String n) { name = n; } String getNam
如果您有这样的关系: 员工与其主管员工之间存在多对一关系 员工与其部门的多对一关系 部门与其经理一对一 我会在 Employee 实体中写入: @ManyToOne (cascade=CascadeT
我是一名优秀的程序员,十分优秀!