【问题标题】:Web2py SQLFORM.grid with executesqlWeb2py SQLFORM.grid 与 executesql
【发布时间】:2015-11-15 12:49:44
【问题描述】:

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

这不是要走的路。

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

谢谢

【问题讨论】:

    标签: python mysql web2py


    【解决方案1】:

    网格设计用于获取表或查询,因此您不能传递 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 会返回一个字典列表,这样可以更轻松地进行插入,因为字典的键是插入所需的字段名称。

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

    【讨论】:

    • 您好,感谢您的回复。因此,即使我这样做,我如何每次使用由 executesql 创建的联合来填充网格?我问这个是因为我的示例被简化了,我想每次为不同的表创建不同的联合。
    • 使用此解决方案,您将不再使用executesql。相反,您直接在生成联合的数据库中定义视图。然后在 web2py 中为该视图定义一个模型。 web2py 不知道视图和常规表之间的区别,因此它会像查询表一样查询视图。当然,您必须为每个可能的联合创建不同的数据库视图。如果有太多的可能性使它变得实用,您可能应该考虑像DataTables 这样的东西,而不是 web2py 网格。
    • 我明白了.. 所以基本上它不能按照我想要的方式完成。非常感谢您的帮助!
    • 一种可能的破解方法是通过executesql 检索数据,然后遍历记录,将每个记录插入到内存中的 SQLite 数据库表中。我将此解决方案添加到答案中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-29
    • 1970-01-01
    • 2012-04-02
    • 2013-05-11
    相关资源
    最近更新 更多