带有executionql的Web2py SQLFORM.grid

时间:2015-11-12 15:03:58

标签: python mysql web2py

我正在创建一个web2py应用程序,我在我的模型db.py文件中定义了两个mysql表:

db.define_table('table1',
    Field('id','integer'),
    Field('name','string'),
    migrate=False)

db.define_table('table2',
    Field('id','integer'),
    Field('name','string'),
    migrate=False)

我希望我的应用程序返回这些表的并集:

data=db.executesql('SELECT * FROM table1 union select * from table2;')

在SQLFORM.grid中,但显然是

form=SQLFORM.grid(data, create=False, deletable=False, editable=False, maxtextlength=100, paginate=10)

不是要走的路。

是的,有人能帮帮我吗?它必须非常简单,但我找不到解决方案。

谢谢

1 个答案:

答案 0 :(得分:4)

网格旨在获取表或查询,因此您无法传递Rows对象或任意SQL。最好的方法是在数据库中创建一个视图并创建一个与该视图关联的新DAL模型定义(确保设置migrate=False,因为您不希望DAL尝试创建一个包含该视图的表。视图的名称)。然后,您可以将视图模型传递给网格:

db.define_table('t1_t2_union_view',
    Field('id','integer'),
    Field('name','string'),
    migrate=False)

grid = SQLFORM.grid(db.t1_t2_union_view, ...)

以上工作原理是因为web2py会像处理任何其他数据库表那样处理数据库视图的模型,并发出查询以选择其所有记录。在这种情况下不需要executesql因为表的并集是由视图在数据库中处理的。

实际上,您可以将表格定义简化为:

db.define_table('t1_t2_union_view', db.table1, migrate=False)

当您将现有表格传递给.define_table()时,您会获得一个与原始表格具有相同字段定义的新表格,这就是我们想要的。

如果为每个可能的联合创建单独的视图是不可行的,可能的替代方法是通过executesql检索数据,然后遍历记录,将每个记录插入到内存中的SQLite数据库表中,然后可以传递到网格:

union_tables = ('table1', 'table2')
temp_db = DAL('sqlite:memory')
union_table = temp_db.define_table('union_table', db[union_tables[0]])

records = db.executesql(sql, as_dict=True)
for record in records:
    union_table.insert(**union_table._filter_fields(record))

grid = SQLFORM.grid(union_table, create=False, editable=False, deletable=False)

设置as_dict=True会导致返回一个字典列表,这样可以更容易地进行插入,因为字典的键是插入所需的字段名称。

请注意,此方法效率较低,因此您必须对其进行测试,以了解它对您的工作负载的影响。