alembic create_table,检查表是不是存在
Posted
技术标签:
【中文标题】alembic create_table,检查表是不是存在【英文标题】:alembic create_table, check if table existsalembic create_table,检查表是否存在 【发布时间】:2015-09-26 18:42:04 【问题描述】:我有一个用于创建表的 alembic 升级脚本,但是如果它已经存在,我不希望它创建该表。
根据alembic doc,我可以将关键字args传递给op.create_tables
,sqlalchemy.schema.table可以接受,所以我使用keep_existing
关键字:
op.create_table('foo_model',
sa.Column('foo_id', sa.Integer(), nullable=False),
sa.Column('foo_str', sa.String(length=255), nullable=True),
sa.PrimaryKeyConstraint('foo_id'),
keep_existing= True
)
但是我仍然收到表已存在错误。
sqlalchemy.exc.InternalError: (InternalError) (1050, u"Table 'foo_model' already exists") '\nCREATE TABLE foo_model (\n\tfoo_id INTEGER NOT NULL AUTO_INCREMENT, \n\tfoo_str VARCHAR(255), \n\tPRIMARY KEY (foo_id)\n)\n\n' ()
【问题讨论】:
见***.com/questions/24082542/… 您检查了为什么keep_existing 不起作用? 【参考方案1】:如果有人愿意,这里有一个完整的解决方案
from alembic import op
from sqlalchemy import engine_from_config
from sqlalchemy.engine import reflection
def _has_table(table_name):
config = op.get_context().config
engine = engine_from_config(
config.get_section(config.config_ini_section), prefix="sqlalchemy."
)
inspector = reflection.Inspector.from_engine(engine)
tables = inspector.get_table_names()
return table_name in tables
【讨论】:
【参考方案2】:您可以像这样获取现有表的列表:
from sqlalchemy.engine.reflection import Inspector
conn = op.get_bind()
inspector = Inspector.from_engine(conn)
tables = inspector.get_table_names()
然后检查表是否已经存在
if table_name not in tables:
op.create_table()
【讨论】:
请注意:Inspector
表示sqlalchemy.engine.reflection.Inspector
我有很多不同版本的 100 多个表,在每个 create_table 上单独检查它似乎不是一个好主意,有什么通用的解决方案吗?【参考方案3】:
正如在其他地方(Check if a table column exists in the database using SQLAlchemy and Alembic)所说,alembic 应该反映数据库的完整状态,这意味着它会自动知道表是否存在。
确保您定义了升级和降级,以便如果升级创建表降级将其删除。
如果您这样做,您只需“降级”到以前的版本并再次升级,它就会起作用。在修订上使用自动生成来创建初始状态。
【讨论】:
【参考方案4】:这可能是因为该表已经存在。只需使用 psql
并运行 drop table foo_model;
从数据库中删除表
【讨论】:
当表已经存在时,这并不能真正解决迁移自己运行良好的问题。 (加上删除表正在丢失数据)以上是关于alembic create_table,检查表是不是存在的主要内容,如果未能解决你的问题,请参考以下文章