我对Python&作为Pyramid的新手(这是我用Python编写的第一件事)并且我在使用数据库查询时遇到了麻烦......
我有以下模型(无论如何都与我的问题相关):
我需要访问MetadataRef中的名称和元数据中的值。
这是我的代码:
class User(Base):
...
_meta = None
def meta(self):
if self._meta == None:
self._meta = {}
try:
for item in DBSession.query(MetadataRef.key, Metadata.value).\
outerjoin(MetadataRef.meta).\
filter(
Metadata.model_id == self.id,
MetadataRef.model == 'User'
):
self._meta[item.key] = item.value
except DBAPIError:
#@TODO: actually do something with this
self._meta = {}
return self._meta
SQLAlchemy生成的查询确实返回了我需要的东西(无论如何足够接近 - 它需要查询model_id作为ON子句的一部分而不是WHERE,但这很小,我很确定我可以自己解决这个问题):
SELECT metadata_refs.`key` AS metadata_refs_key, metadata.value AS metadata_value
FROM metadata_refs LEFT OUTER JOIN metadata ON metadata_refs.id = metadata.metadata_ref_id
WHERE metadata.model_id = %s AND metadata_refs.model = %s
但是,当我访问对象时,我收到此错误:
AttributeError: 'KeyedTuple' object has no attribute 'metadata_value'
这让我觉得我还有其他一些方法可以访问它,但我无法弄清楚如何。我已经尝试了.value
和.metadata_value
。 .key
确实按预期工作。
有什么想法吗?
答案 0 :(得分:1)
您正在查询单独的属性(SA文档中的“启用ORM的描述符”):
DBSession.query(MetadataRef.key, Metadata.value)
在这种情况下,查询不返回完整的ORM映射对象,而是返回KeyedTuple,它是元组和对象之间的交叉,其属性对应于字段的“标签”。
因此,访问数据的一种方法是索引:
ref_key = item[0]
metadata_value = item[1]
或者,要使SA使用列的特定名称,您可以使用Column.label()方法:
for item in DBSession.query(MetadataRef.key.label('ref_key'), Metadata.value.label('meta_value'))...
self._meta[item.key] = item.meta_value
对于调试,您可以使用Query.column_descriptions()方法,该方法将告诉您查询返回的列的名称。