受这个问题的启发:如何在SQLAlchemy中删除表格?,我最终提出了一个问题:如何删除多个表格。
假设我有以下3个表格,并且我想要删除其中2个表格(想象一下有很多表格,因此不能手动删除表格)。
表格
import sqlalchemy as sqla
import sqlalchemy.ext.declarative as sqld
import sqlalchemy.orm as sqlo
sqla_base = sqld.declarative_base()
class name(sqla_base):
__tablename__ = 'name'
id = sqla.Column(sqla.Integer, primary_key=True)
name = sqla.Column(sqla.String)
class job(sqla_base):
__tablename__ = 'job'
id = sqla.Column(sqla.Integer, primary_key=True)
group = sqla.Column(sqla.String)
class company(sqla_base):
__tablename__ = 'company'
id = sqla.Column(sqla.Integer, primary_key=True)
company = sqla.Column(sqla.String)
engine = sqla.create_engine("sqlite:///test.db", echo=True)
sqla_base.metadata.bind = engine
# Tables I want to delete
to_delete = ['job', 'function']
# Get all tables in the database
for table in engine.table_names():
# Delete only the tables in the delete list
if table in to_delete:
sql = sqla.text("DROP TABLE IF EXISTS {}".format(table))
engine.execute(sql)
# Making new tables now the old ones are deleted
sqla_base.metadata.create_all(engine)
如何在SQLAlchemy中实现?编辑
这个方法可以工作,但我想知道是否可以使用SQLAlchemy的方式来执行相同的操作,而不是使用sqla.text("DROP TABLE IF EXISTS {}".format(table))
(不使用sqla_base.metadata.drop_all()
,因为那会删除所有表)。
我知道存在函数tablename.__table__.drop()
或tablename.__table__.drop(engine)
,但我不想手动为每个表输入代码。
根据@daveoncode提供的答案,以下代码可以实现我的需求(编辑2:添加checkfirst=True
,以防它在数据库中不存在和使用str()
):
for table in sqla_base.metadata.sorted_tables:
if str(table) in self.to_delete:
table.drop(checkfirst=True)
问题
如何以SQLAlchemy风格删除多个表,实现与上面的原始SQL代码相同的效果?
for table in sqla_base.metadata.tables:
,但那也返回了一个字符串。根据您的建议:for table in sqla_base.metadata.sorted_tables:
可以工作 :) 我没想到会这样工作,因为.tables
只返回一个字符串,那么为什么.sorted_tables
会返回一个表实例呢?(而且我不需要排序)。 - NumesSanguisdrop_all
,因为我的意图是仅删除特定的表。我更新了我的问题(请参见编辑),包括使用您的sorted_tables
获得的工作代码。谢谢。 - NumesSanguis