【问题标题】:Weird behavior with web2py DAL on table definitionweb2py DAL 在表定义上的奇怪行为
【发布时间】:2014-12-18 02:43:59
【问题描述】:

你好,我不理解 web2py 的行为

In [50]: db = DAL('sqlite://deposit/sample.sqlite')

In [51]: db.define_table('customer',Field('name','string',required=True),
     Field('nric','string',required=True),
     Field('address','string'),
     Field('phone','integer'),
     primarykey=['name'])
Out[51]: <Table customer (name,nric,address,phone)>

按预期工作。

然后我做

In [53]: db.define_table('check',
         Field('nric', db.customer.nric, required=True), 
         Field('clear','string'))

这让我得到了消息

AttributeError: 'DAL' object has no attribute 'customer.nric'

所以认为这可能是没有将customer 提交到数据库的问题

所以我做了一个db.commit() 然后再试一次

In [56]: db.define_table('check',Field('nric', db.customer.nric, required=True), Field('clear','string'))
  File "<string>", line unknown
SyntaxError: table already defined: check

不知道为什么..但无论如何我试着放下桌子

In [59]: db['check'].drop()

并得到以下奇怪的回溯

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-59-998297b798f5> in <module>()
----> 1 db['check'].drop()

/home/tahnoon/.dropbox-cyn/Dropbox (TIS Group)/Cynopsis/Builds/Apollo/Code Src/web2py/gluon/dal.pyc in drop(self, mode)
   9225 
   9226     def drop(self, mode=''):
-> 9227         return self._db._adapter.drop(self, mode)
   9228 
   9229     def _listify(self, fields, update=False):

/home/tahnoon/.dropbox-cyn/Dropbox (TIS Group)/Cynopsis/Builds/Apollo/Code Src/web2py/gluon/dal.pyc in drop(self, table, mode)
   1328         queries = self._drop(table, mode)
   1329         for query in queries:
-> 1330             if table._dbt:
   1331                 self.log(query + '\n', table)
   1332             self.execute(query)

/home/tahnoon/.dropbox-cyn/Dropbox (TIS Group)/Cynopsis/Builds/Apollo/Code Src/web2py/gluon/dal.pyc in __getitem__(self, key)
   9108             return self._db(self._id == key).select(limitby=(0, 1), orderby_on_limitby=False).first()
   9109         elif key:
-> 9110             return ogetattr(self, str(key))
   9111 
   9112     def __call__(self, key=DEFAULT, **kwargs):

AttributeError: 'Table' object has no attribute '_dbt'

检查表显示

In [61]: db.tables()
Out[61]: ['customer']

这是预期的行为吗?如果是这样,在语法错误后如何删除/创建表?谢谢

【问题讨论】:

    标签: database web2py


    【解决方案1】:

    由于db.customer 是带键表(即您定义了primarykey 属性而不是依赖默认的自增整数ID 字段作为主键),它只能被其他带键表引用。

    此外,在为键控表创建参考字段时,请使用以下语法:

    Field('nric', 'reference customer.nric', required=True)
    

    但是,我认为 SQLite 不支持键控表(文档说只支持 DB2、MS-SQL、Ingres 和 Informix)。无论如何,如果您在 SQLite 中创建新表,则没有理由使用键控表(添加该功能主要是为了启用对缺少自动增量整数主键字段的旧数据库的访问)。

    最后,删除表并不会从db DAL 实例中删除模型——相反,该操作会从数据库本身中删除表。如果你想在 shell 会话中重新定义模型,你应该使用“redefine”参数:

    db.define_table(..., redefine=True)
    

    【讨论】:

    • 谢谢@Anthony。这正是我所需要的。快速跟进,如果该字段在第二个表中具有不同的名称怎么办,这可能吗?如果是这样,我如何让 web2py 知道要引用哪些字段?
    • 对不起,对答案进行了一些更正。使用键控表,您可以指定表和字段名称,如上所示。但是,我不认为 SQLite 完全支持键控表,因此您可能会遇到一些错误。
    猜你喜欢
    • 2014-01-09
    • 2019-06-24
    • 2014-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    • 2015-08-27
    • 2014-01-26
    相关资源
    最近更新 更多