金字塔/ SQLAlchemy加入模型的麻烦

时间:2014-06-30 23:40:40

标签: python sqlalchemy pyramid

我对Python&作为Pyramid的新手(这是我用Python编写的第一件事)并且我在使用数据库查询时遇到了麻烦......

我有以下模型(无论如何都与我的问题相关):

  • MetadataRef(包含有关给定元数据类型的信息)
  • 元数据(包含实际元数据) - 这是MetadataRef的子元素
  • 用户(包含用户) - 这与元数据相关联。 MetadataRef.model ='User'和metadata.model_id = user.id

我需要访问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确实按预期工作。

有什么想法吗?

1 个答案:

答案 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()方法,该方法将告诉您查询返回的列的名称。