我想删除数据库db
中的所有表。我所做的就是遍历db.tables
和
一个接一个地放下它们。但是,某些表会被忽略,因此不会被删除。然后我
将drop
更改为truncate
,每个表都被截断。那么,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中的drop
更改为truncate
,则输出将为
['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']
只有第二行的表格被删除。
答案 0 :(得分: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()将从db.tables
中删除table_name,但不会从for循环迭代的db.tables()
副本中删除它,因此一切都应按预期工作。