在Pyramid中创建sqlalchemy查询对象的字典

Rol*_*ish 1 python sqlalchemy pyramid

我是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
Run Code Online (Sandbox Code Playgroud)

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

myvar = [user.name for user in users]
Run Code Online (Sandbox Code Playgroud)

那么,我遇到的另一个问题是:是否有像上面这样的"一行"方式来创建sqlalchemy查询对象的字典?

提前致谢.

Sin*_*ion 7

嗯,是的,我们可以收紧一点.

首先,这种模式:

 index = 0
 for item in seq:
     frobnicate(index, item)
     item += 1
Run Code Online (Sandbox Code Playgroud)

很常见,有一个自动执行的内置函数,enumerate()像这样使用:

 for index, item in enumerate(seq):
     frobnicate(index, item)
Run Code Online (Sandbox Code Playgroud)

但是,我不确定你是否需要它,将事物与从零开始的整数索引相关联是一个列表的功能,你真的不需要一个字典; 除非你想要漏洞,或者需要一些其他特殊功能,否则只需:

 stuff = []
 stuff.extend(seq)
Run Code Online (Sandbox Code Playgroud)

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

 query = DBSession.query(Client.id, Client.name) \
                  .filter(q in Client.name)
Run Code Online (Sandbox Code Playgroud)

在上面我也缩短.name.like('%%%s%%' % q)到仅仅q in name因为它们意味着同样的事情(SQLAlchemy的它扩展到正确的LIKE为你表达)

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

所以把它们放在一起

output = [row._asdict() for row in DBSession.query(Client.id, Client.name)
                                            .filter(q in Client.name)]
Run Code Online (Sandbox Code Playgroud)

或者,如果你真的迫切需要它成为一个词典,你可以使用词典理解:

output = {index: row._asdict() 
          for index, row 
          in enumerate(DBSession.query(Client.id, Client.name)
                                .filter(q in Client.name))}
Run Code Online (Sandbox Code Playgroud)