根据标题this判断是完全相同的问题,但我无法看到任何答案如何适用于我的用例:
我有两个班级和他们之间的关系:
treatment_association = Table('tr_association', Base.metadata,
Column('chronic_treatments_id', Integer, ForeignKey('chronic_treatments.code')),
Column('animals_id', Integer, ForeignKey('animals.id'))
)
class ChronicTreatment(Base):
__tablename__ = "chronic_treatments"
code = Column(String, primary_key=True)
class Animal(Base):
__tablename__ = "animals"
treatment = relationship("ChronicTreatment", secondary=treatment_association, backref="animals")
我希望能够只选择具有代码" X"处理不足的动物。我尝试了很多方法。
这个失败了AttributeError
:
sql_query = session.query(Animal.treatment).filter(Animal.treatment.code == "chrFlu")
for item in sql_query:
pass
mystring = str(session.query(Animal))
这个人很高兴地返回一份未经过滤的动物名单:
sql_query = session.query(Animal.treatment).filter(ChronicTreatment.code == "chrFlu")
for item in sql_query:
pass
mystring = str(session.query(Animal))
最接近上述线程的例子我可以放在一起:
subq = session.query(Animal.id).subquery()
sql_query = session.query(ChronicTreatment).join((subq, subq.c.treatment_id=="chrFlu"))
for item in sql_query:
pass
mystring = str(session.query(Animal))
mydf = pd.read_sql_query(mystring,engine)
AttributeError
也失败了。
你能告诉我这份清单吗?
答案 0 :(得分:1)
首先,表定义存在两个问题:
1)treatment_association
Integer
列chronic_treatments.code
列指向code
而String
为id
列。
我认为在chronic_treatments
中有一个整数Animal
会更好,所以你不要在另一个表中复制字符串代码并且还有机会添加稍后会有更多领域到chronic_treatments。
更新:不完全正确,您仍然可以添加更多字段,但更改您的代码会变得更加复杂。如果你决定重命名它。
2)在treatment
模型中,您有一个名为treatments
的关系。这很令人困惑,因为你有多对多的关系,它应该是复数 - treatment
。
修正上述两项后,应该更清楚为什么你的查询不起作用。
这一个(我将treatments
替换为sql_query = session.query(Animal.treatments).filter(
Animal.treatments.code == "chrFlu")
:
Animal.treatments
query
表示多对多关系,它不是SQL Alchemy模式,因此您无法将其传递给filter
,也无法在Animal.treatments
中使用}。
下一个因为同样的原因无法工作(您将query
传递到join
。
最后一个更接近,您实际上需要animals = session.query(Animal).from_statement(text(
"""
select distinct animals.* from animals
left join tr_association assoc on assoc.animals_id = animals.id
left join chronic_treatments on chronic_treatments.id = assoc.chronic_treatments_id
where chronic_treatments.code = :code
""")
).params(code='chrFlu')
才能获得结果。
我认为将查询理解为SQL更容易(无论如何你需要知道SQL能够使用sqlalchemy):
animals
它会选择chronic_treatments
并通过tr_association
加入sql_query = session.query(Animal).join(Animal.treatments).filter(
ChronicTreatment.code == "chrFlu")
并按代码过滤结果。
有了这个,很容易使用无SQL语法重写它:
<Style TargetType="TextBox" >
<Setter Property="OverridesDefaultStyle" Value="false"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Margin" Value="5,3" />
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="FocusManager.FocusedElement" Value="{Binding RelativeSource={RelativeSource Self}}"/>
</Trigger>
</Style.Triggers>
</Style>
这将返回你想要的东西 - 一份与给定代码有相关长期治疗的动物清单。