Web2py SQLFORM.grid 与 executesql

Web2py SQLFORM.grid with executesql

我正在制作一个 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)

我希望我的应用程序 return 这些表的联合:

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)

不是正确的选择。

有人可以帮帮我吗?它一定很简单,但我找不到解决方案。

谢谢

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

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

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

上面的工作是因为 web2py 将像对待任何其他数据库一样对待数据库视图的模型 table,向 select 它的所有记录发出查询。在这种情况下不需要 executesql,因为 table 的并集由视图在数据库中处理。

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

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

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

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

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会导致返回字典列表,这使得插入更容易,因为字典的键是插入所需的字段名称。

请注意,此方法有些低效,因此您必须对其进行测试以了解它如何处理您的工作负载。