2010-05-13 59 views
7

我已经将SQLAlchemy更新为0.6,但它打破了一切。我注意到它返回的元组不再是字典了。下面是一个示例查询:SQLAlchemy返回元组不是字典

query = session.query(User.id, User.username, User.email).filter(and_(User.id == id, User.username == username)).limit(1) 
result = session.execute(query).fetchone() 

这段代码用于返回0.5中的字典。

我的问题是如何返回字典?

+2

只是好奇:为什么不'''' 。或'session.query(User).filter(User.id == id).filter(User.username == username).first()'如果id不是主键。做到这一点,您将获得一个User实例,并且您可以通过属性查找来访问字段值。 – codeape 2010-05-14 05:25:13

回答

5

这应该工作: dict(zip(['id','username','email'],result))(或者如果你使用Python 3.x,你可以使用字典理解)。
此外,您不需要拨打session.execute上的session.query对象。您需要改为使用.one()方法。这也避免了在查询结束时挂起.limit(1)呼叫的需要。

+0

是的,它的工作原理。谢谢。我使用limit(1),因为当我查看SQLALchemy为此代码创建的SQL语句时,它不包含查询中的LIMIT 1。 – Ivan 2010-05-13 17:04:19

8

你确定它不是一个ResultProxy它打印时假装是一个元组? ORM中的许多对象不是它们的__str__函数返回的内容。

+0

+1我完全被我所看到的直视,直到我读到这个。读完之后,我继续尝试使用字段名称,并且它完美地工作!为我节省了很多头痛。谢谢。 – 2014-02-12 16:12:28

33

session.execute从未返回一个字典,它返回一个RowProxy对象,可以使用用于位置查找任一整数密钥被索引一个字典,字符串键用于标签基于查找向上或Column对象来查找值该列。这里的问题是session.execute(query)没有达到你期望的效果。它将Query对象转换为Select语句,执行该语句并直接返回结果。结果集不知道任何有关ORM级别功能的信息。 0.5和0.6之间的变化是ORM使用不同的算法来标记查询中的列,现在它将表名称预先标记为标签。所以当以前row['id']碰巧工作,现在row['users_id']工作。在这两种情况下row[User.__table__.columns['id']]的作品。

要执行ORM查询,您应该实际使用.all(),.first().one()方法或对其进行迭代或使用数字索引。查询返回指定的元组对象。如果你想要一个字典,用它的键将元组压缩:

row = session.query(User.id, User.username, User.email)\ 
    .filter(and_(User.id == id, User.username == username)).first() 
print("id=%s username=%s email=%s" % row) # positional 
print(row.id, row.username) # by label 
print(dict(zip(row.keys(), row))) # as a dict