0

我想删除数据库中的所有表db。我所做的就是遍历db.tables并一一删除它们。但是,某些表会被忽略,因此不会被删除。然后我改为droptruncate每个表都被截断。那么,有什么问题drop呢?

以下是代码:

控制器/admin.py:

def olddo_remove():
    response.view = 'admin/do_remove.html'
    l = []
    k = []
    for table_name in db.tables:
        l.append(table_name)
        db[table_name].drop()
        #db[table_name].truncate()
    return locals()

def do_remove():
    l = []
    k = []
    for table_name in db.tables:
        l.append(table_name)
    for table_name in l:
        k.append(table_name)
        db[table_name].drop()
    return locals()

意见/管理/do_remove.html:

{{=l}}<br />{{=k}}

当我访问 admin/olddo_remove 时,我得到

['auth_user', 'auth_membership', 'auth_event', 'client', 'data']
[] 

当我访问 admin/do_remove 时,我得到

['auth_user', 'auth_group', 'auth_membership', 'auth_permission', 'auth_event', 'auth_cas', 'client', 'product', 'data']
['auth_user', 'auth_group', 'auth_membership', 'auth_permission', 'auth_event', 'auth_cas', 'client', 'product', 'data'] 

如果我在 olddo_remove 中更改为droptruncate输出将是

['auth_user', 'auth_group', 'auth_membership', 'auth_permission', 'auth_event', 'auth_cas', 'client', 'product', 'data']
[] 

为什么?怎么了?


太疯狂了!

def test():
    response.view = 'admin/do_remove.html'
    l = db.tables
    k = []
    for table_name in l:
        k.append(table_name)
        db[table_name].drop()
    return locals()

输出:

['auth_group', 'auth_permission', 'auth_cas', 'product']
['auth_user', 'auth_membership', 'auth_event', 'client', 'data'] 

并且只删除了第二行的表格。

4

1 回答 1

2

这是一个 Python 问题。db.tables是一个列表对象(实际上是一个特殊的 SQLCallableList 对象,继承自列表)。db[table_name].drop()不仅从数据库中删除 table_name 表,而且从db.tables列表中删除 table_name。因此,在 for 循环中,您正在迭代一个列表并在迭代时改变该列表(即从中删除项目)。这就是为什么你只得到其他所有桌子的原因。在有效的示例中,您首先复制列表,然后迭代副本(在循环中不会发生变异),因此它按预期工作。截断即使在直接迭代时也有效,db.tables因为截断不会删除表(从数据库或从db.tables)。

注意,如上所述,db.tables是一个 SQLCallableList。这意味着db.tables()返回db.tables列表的副本,因此您可以迭代副本:

for table_name in db.tables():
    db[table_name].drop()

.drop() 将从中删除 table_namedb.tables但不会从db.tables()for 循环正在迭代的副本中删除它,因此一切都应该按预期工作。

于 2012-07-28T20:26:37.783 回答