Python 如何使用int而不是实例查询sqlalchemy关系?
我有两个模型,Foo和Bar。Bar与Foo有一对多关系,有一个“Foo_id”列和一个“Foo”关系。我想查询foo_id=1的酒吧行 据我所知,有两种工作方法可以做到这一点:Python 如何使用int而不是实例查询sqlalchemy关系?,python,orm,sqlalchemy,Python,Orm,Sqlalchemy,我有两个模型,Foo和Bar。Bar与Foo有一对多关系,有一个“Foo_id”列和一个“Foo”关系。我想查询foo_id=1的酒吧行 据我所知,有两种工作方法可以做到这一点: 访问基础外键列对象:query.filter(Bar.foo\u id==1) 获取一个Foo实例,并执行query.filter(Bar.Foo==instance) 我希望这两种方法的替代方法更像query.filter(Bar.foo==1)——也就是说,使用relationship列和普通整数而不是实例。此操作
query.filter(Bar.foo\u id==1)
query.filter(Bar.Foo==instance)
query.filter(Bar.foo==1)
——也就是说,使用relationship列和普通整数而不是实例。此操作当前失败,原因是AttributeError:“int”对象没有属性“\u sa\u instance\u state”
我不想使用上述两种方法的原因:
foo_id
列的名称-所有表元数据都是通过反射生成的,列名称是我不希望依赖的实现细节(它们目前非常不一致,并且正在使用alembic迁移重命名,因此不希望依赖于这些名称)from sqlalchemy import create_engine, Column, Integer, ForeignKey
from sqlalchemy.orm import relationship, Session
from sqlalchemy.ext.declarative import declarative_base
def method_1(session, some_foo_id):
"""Works, but i don't actually know foo_id"""
session.query(Bar).filter(Bar.foo_id == some_foo_id).first()
def method_2(session, some_foo_id):
"""Works, but adds a pointless roundtrip"""
some_foo = session.query(Foo).get(some_foo_id)
session.query(Bar).filter(Bar.foo == some_foo).first()
def method_3(session, some_foo_id):
"""Throws an exception, passing int instead of instance"""
session.query(Bar).filter(Bar.foo == some_foo_id).first()
# database setup follows
Base = declarative_base()
class Foo(Base):
__tablename__ = 'foo'
id = Column(Integer, primary_key=True)
value = Column(Integer)
class Bar(Base):
__tablename__ = 'bar'
id = Column(Integer, primary_key=True)
foo_id = Column(Integer, ForeignKey('foo.id'))
foo = relationship(Foo)
if __name__ == '__main__':
engine = create_engine('sqlite://')
Base.metadata.create_all(engine)
session = Session(bind=engine)
foo1, foo2 = Foo(value=1), Foo(value=2)
bar1, bar2 = Bar(foo=foo1), Bar(foo=foo2)
session.add_all([foo1, foo2, bar1, bar2])
session.commit()
engine.echo = True
for fun in [method_1, method_2, method_3]:
print("\n---> %s (%s)\n" % (fun.__name__, fun.__doc__))
fun(session, 1)
session.rollback()
输出:
-->method_1(有效,但我实际上不知道foo_id
开始(隐式)
选择bar.id作为bar\u id,选择bar.foo\u id作为bar\u foo\u id
从酒吧
其中bar.foo_id=?
限制?抵消?
(1, 1, 0)
回降
--->方法2(有效,但添加了无意义的往返)
开始(隐式)
选择foo.id作为foo\u id,选择foo.value作为foo\u value
来自富
其中foo.id=?
(1,)
选择bar.id作为bar\u id,选择bar.foo\u id作为bar\u foo\u id
从酒吧
哪里?=bar.foo\u id
限制?抵消?
(1, 1, 0)
回降
--->方法3(抛出异常,传递int而不是instance)
回溯(最近一次呼叫最后一次):
文件“asd.py”,第51行,在
乐趣(第1节)
文件“asd.py”,第19行,在方法_3中
session.query(Bar.filter)(Bar.foo==some\u foo\u id).first()
文件“/usr/lib/python2.7/site packages/sqlalchemy/sql/operators.py”,第304行,在__
返回自操作(eq,其他)
文件“/usr/lib/python2.7/site packages/sqlalchemy/orm/attributes.py”,第175行,在operate中
返回op(自比较器,*其他,**kwargs)
文件“/usr/lib/python2.7/site packages/sqlalchemy/orm/relationships.py”,第1042行,在__
其他,adapt_source=self.adapter)
文件“/usr/lib/python2.7/site packages/sqlalchemy/orm/relationships.py”,第1369行,在“优化”比较中
状态=属性。实例\状态(状态)
AttributeError:“int”对象没有属性“\u sa\u instance\u state”
找到了一种方法,Bar.foo.prop.local\u columns
是RelationshipProperty的一个属性,它返回一个通常包含一个项的集合(对于像这样的简单关系)。集合是无序的,您不能只获取第一项,因此列表(…)[0]
。完整代码:
def方法4(会话,一些foo-id):
foo\u col=list(Bar.foo.prop.local\u列)[0]
session.query(Bar).filter(foo\u col==some\u foo\u id).first()