1

我是 Python 和 Pyramid 的新手。在我用来了解更多有关 Pyramid 的测试应用程序中,我想查询数据库并根据 sqlalchemy 查询对象的结果创建字典,最后将字典发送到变色龙模板。

到目前为止,我有以下代码(工作正常),但我想知道是否有更好的方法来创建我的字典。

...
index = 0
clients = {}
q = self.request.params['q']
for client in DBSession.query(Client).filter(Client.name.like('%%%s%%' % q)).all():
    clients[index] = { "id": client.id, "name": client.name }
    index += 1
output = { "clients": clients }

return output

在学习 Python 时,我发现了一种在 for 循环语句中创建列表的好方法,如下所示:

myvar = [user.name for user in users]

那么,我遇到的另一个问题是:是否有类似上述的“单行”方式来创建 sqlalchemy 查询对象的字典?

提前致谢。

4

3 回答 3

7

嗯,是的,我们可以稍微收紧一点。

首先,这个模式:

 index = 0
 for item in seq:
     frobnicate(index, item)
     item += 1

很常见,有一个内置函数可以自动执行它enumerate(),使用如下:

 for index, item in enumerate(seq):
     frobnicate(index, item)

但是,我不确定您是否需要它,将事物与从零开始的整数索引关联是列表的功能,您实际上并不需要 dict;除非你想有漏洞,或者需要dicts的其他一些特殊功能,否则只需执行以下操作:

 stuff = []
 stuff.extend(seq)

当您只对数据库实体的一小部分属性感兴趣时,最好告诉 sqlalchemy 发出只返回以下内容的查询:

 query = DBSession.query(Client.id, Client.name) \
                  .filter(q in Client.name)

在上面我也缩短了.name.like('%%%s%%' % q)into 只是q in name因为它们的意思相同(sqlalchemy 将它扩展LIKE为你的正确表达式)

以这种方式构造的查询返回一个看起来像元组的特殊事物,并且可以通过调用它轻松地变成一个字典_asdict()

所以把它们放在一起

output = [row._asdict() for row in DBSession.query(Client.id, Client.name)
                                            .filter(q in Client.name)]

或者,如果你真的非常需要它成为一个字典,你可以使用一个字典理解:

output = {index: row._asdict() 
          for index, row 
          in enumerate(DBSession.query(Client.id, Client.name)
                                .filter(q in Client.name))}
于 2013-07-17T20:11:23.327 回答
3

@TokenMacGuy 对您的问题给出了一个很好而详细的答案。但是,我感觉您问了一个错误的问题:)

在将 SQLALchemy 对象传递给模板之前,您不需要将它们转换为字典 - 这会非常不方便。您可以按原样传递查询结果并直接在模板中使用 SQLALchemy 映射对象

q = self.request.params['q']
clients = DBSession.query(Client).filter(q in Client.name).all()
return {'clients': clients}
于 2013-07-17T20:47:15.043 回答
0

如果要将 SqlAlchemy 对象转换为 dict,可以使用以下代码:

def obj_to_dict(obj):
    return dict((col.name, getattr(obj, col.name)) for col in sqlalchemy_orm.class_mapper(obj.__class__).mapped_table.c)

映射表的另一个属性包含其中的关系,但代码变得冒险。

您不需要将对象转换为任何模板库的 dict,但如果您决定保留数据(memcached、session、pickle 等),您将需要使用 dicts 或编写一些代码到 '将持久化的数据合并回会话中。

一个快速的旁注 - 如果您通过 json 渲染任何这些数据,您将需要一个可以处理 datetime objects 的自定义 json 渲染器,或者更改函数中的值。

于 2013-07-24T15:04:48.023 回答