Правильный метод инициализации таблицы базы данных с помощью web2py DAL.define_table ()

Я пытаюсь динамически создавать таблицы с именами db.blog и db.code с точно такими же определениями SQL. После того, как я их определю, я хочу заполнить их 10 строками случайных данных и никогда больше не выполнять этот код инициализации.

Моя проблема в том, что код инициализации выполняется каждый раз, когда я нажимаю кнопку «Обновить» в браузере, пока я просматриваю интерфейс приложения newblog для db.code или db.blog : https://172.25.1.1/newblog/appadmin/select/db?query=db.code.id >0

Я инициализирую db.blog и db.code в newblog / 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()

Каким-то образом , если не db.get (tt, False): , разрешает многократное выполнение подпрограммы под ним. Я не понимаю, почему ... если таблица уже была создана, то , а не db.get (tt, False) должно быть False . Однако web2py никогда не пропускает код инициализации, что означает увеличение db.blog и db.code на 10 записей при каждой перезагрузке.

Вопрос: Почему нет , если не db.get (tt, False): предотвращает множественное выполнение?

Я использую web2py 1.99.4 на Debian 6.0 / sqlite 3.7. 3 / Cherokee 1.2.101 / uWSGI 0.9.9.3

Решение

На основании ответа 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()

Теперь db.blog и db.code остаются постоянного размера.

Сводка

db.define_tables () должен вызываться для каждого рендеринга страницы; мое понимание (что для записи определения таблицы на диск нужно было запустить только один раз) было неверным.

8
задан Mike Pennington 28 December 2011 в 19:26
поделиться