使用web2py DAL.define_table()初始化数据库表的正确方法

Mik*_*ton 8 python database web2py

我正在尝试动态构建调用的表,db.blogdb.code使用完全相同的SQL定义.在我定义它们之后,我想用10行随机数据填充它们,并且永远不再执行该初始化代码.

我的问题是每当我在浏览器上点击刷新时执行初始化代码,而我查看newblog appadmin接口db.codedb.blog:https://172.25.1.1/newblog/appadmin/select/db?query = db.code.id > 0

我初始化db.blogdb.codenewblog/models/newblog.py:

from gluon import *
from gluon.contrib.populate import populate

## initialize db.blog and db.code: 
##     At runtime, build TAGGED_TABLES (once)
TAGGED_TABLES = set(['blog', 'code'])
for tt in TAGGED_TABLES:
    if not db.get(tt, False):
        db.define_table(tt,
            Field('name', length=32, notnull=True),
            Field('value', length=65535, notnull=True),
            Field('tags', type='list:reference tag', unique=False, notnull=False),
            )

        populate(db.get(tt), 10)

        ## cross-reference db.tagged_tables to this one
        db.tagged_tables.insert(name=tt,
            database_pointer='reference %s' % tt)
        db.commit()
Run Code Online (Sandbox Code Playgroud)

不知何故if not db.get(tt, False):允许多次执行它下面的例程.我不明白为什么......如果表已经创建,那么not db.get(tt, False)应该是False.然而,web2py会从来没有跳过初始化代码,这意味着db.blogdb.code通过对每个重载10项增长.

问题:为什么不if not db.get(tt, False):阻止多次执行?

我在Debian 6.0/sqlite 3.7.3/Cherokee 1.2.101/uWSGI 0.9.9.3上运行web2py 1.99.4

根据Interrobang的回答,正确的写法是:

from gluon import *
from gluon.contrib.populate import populate


TAGGED_TABLES = set(['blog', 'code'])
for tt in TAGGED_TABLES:
    # db.define_table() must be called on **every page**
    #    this sets things up in memory...
    db.define_table(tt,
        Field('name', length=32, notnull=True),
        Field('value', length=65535, notnull=True),
        Field('tags', type='list:reference tag', unique=False, notnull=False),
        )

    ## initialize db.blog and db.code: 
    ##     At runtime, populate tables named in TAGGED_TABLES (once)
    if not (db(db.get(tt).id>0).select()):
        populate(db.get(tt), 10)
        ## cross-reference db.tagged_tables to this table (named in var tt)
        db.tagged_tables.insert(name=tt,
            database_pointer='reference %s' % tt)
        db.commit()
Run Code Online (Sandbox Code Playgroud)

现在db.blog,db.code保持不变的大小.

摘要

db.define_tables()必须为每个页面渲染调用; 我的理解(它只需要运行一次将表定义写入磁盘)是不正确的.

Int*_*ang 5

您可以添加一个fixtures文件,该文件基本上包含在创建表时要插入一次的默认数据.

这里给出一个例子:http://thadeusb.com/weblog/2010/4/21/using_fixtures_in_web2py