Я пытаюсь динамически создавать таблицы с именами 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 ()
должен вызываться для каждого рендеринга страницы; мое понимание (что для записи определения таблицы на диск нужно было запустить только один раз) было неверным.