我正在制作一个 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)
不是要走的路。
有人可以帮帮我吗?它一定非常简单,但我找不到解决方案。
谢谢
最佳答案
网格旨在获取表格或查询,因此您不能传递 Rows
对象或任意 SQL。最好的方法是在数据库中创建一个 View 并创建一个与该 View 关联的新 DAL 模型定义(确保设置 migrate=False
,因为您不希望 DAL 尝试使用 View 的名称创建一个表)。然后你可以将 View 模型传递给网格:
db.define_table('t1_t2_union_view',
Field('id','integer'),
Field('name','string'),
migrate=False)
grid = SQLFORM.grid(db.t1_t2_union_view, ...)
上面的工作是因为 web2py 将像对待任何其他数据库表一样对待数据库 View 的模型,发出查询以选择其所有记录。在这种情况下不需要 executesql
,因为表的合并由 View 在数据库中处理。
实际上,您可以将表定义简化为:
db.define_table('t1_t2_union_view', db.table1, migrate=False)
当您将现有表传递给 .define_table()
时,您会得到一个与原始表具有相同字段定义的新表,这正是我们在这里想要的。
如果为每个可能的联合创建单独的 View 不可行,一种可能的替代方法是通过 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
会导致返回字典列表,这使得插入更容易,因为字典的键是插入所需的字段名称。
请注意,此方法有些低效,因此您必须对其进行测试以了解它如何处理您的工作负载。
关于python - Web2py SQLFORM.grid 与 executesql,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33674532/