Python 防止alembic自动生成表

Python 防止alembic自动生成表,python,flask,sqlalchemy,alembic,Python,Flask,Sqlalchemy,Alembic,我是新来的如此alembic,所以我可能会错过它的概念中的一点,但问题是 我在烧瓶应用程序中有一些sqlalchemy表,如下所示: class Data(Base): __tablename__ = 'Data' __table_args__ = {'schema': 'schema'} id = Column(Integer, primary_key=True) name = Column(String, nullable=False) 我初始化我的表: Base = declarativ

我是新来的如此alembic,所以我可能会错过它的概念中的一点,但问题是

我在烧瓶应用程序中有一些sqlalchemy表,如下所示:

class Data(Base):
__tablename__ = 'Data'
__table_args__ = {'schema': 'schema'}
id = Column(Integer, primary_key=True)
name = Column(String, nullable=False)
我初始化我的表:

Base = declarative_base()
engine = create_engine(db_link, pool_size=100, max_overflow=0)
Base.metadata.create_all(engine)
Session = sessionmaker()
Session.configure(bind=engine)
在这一点上,我在数据库中手动创建了表,一切都很顺利。 为了使我的项目更具成效,我希望能够使用alembic迁移我的数据库。因为我将使用的一些表(在不同的模式中)是只读的,并且是由另一个程序创建的,所以我只想迁移一些sqlalchemy表。因此,我的升级脚本如下所示(由alembic revision--autogenerate创建):

当我现在使用空数据库将架构迁移到以下位置时:

alembic upgrade head
我得到以下错误:

sqlalchemy.exc.ProgrammingError: (pyodbc.ProgrammingError) ('42S01', "[42S01] [M
icrosoft][SQL Server Native Client 11.0][SQL Server]There is already an object n
amed 'Data' in the database. (2714) (SQLExecDirectW)") [SQL: '\nCREATE TABLE schema.
[Data] (\n\tid INTEGER NOT NULL IDENTITY(1,1), \n\tname VARCHAR(max) NOT NULL, \
 \n\tPRIMARY KEY (id), \n\tCHECK (IN (0, 1))\n)\n\n']

看起来alembic会自动创建所有表,然后再次尝试在我的修订脚本中创建这些表。如果这是真的,我如何告诉alembic不要自动创建任何表,而只运行我创建的脚本?

您的迁移会显式创建一个
数据
表:

def upgrade():
    ...
    op.create_table('Data',
    ...
因此,如果您的
数据
表已经存在,因为您已经手动创建了它,那么出现错误是正常的

编辑: 我不确定它是何时执行的,但您可能希望尝试注释数据库初始化脚本中的
Base.metadata.create_all(engine)
行。我怀疑这是为了创建表。 我从未见过alembic在运行迁移之前创建表(这是迁移创建表的工作),如果它不能解决您的问题,我认为问题不是alembic造成的


Alembic旨在从一开始就管理数据库迁移,它并不假定您已经创建了表

基本上,它创建一个表来保存应用于数据库的迁移历史记录。当您运行第一次升级时,尚未应用迁移,因此Alembic将尝试运行从根版本(其
向下修订版
)到头版本的所有迁移升级。 在每次应用迁移时,它还更新其历史记录表以反映数据库状态

您可以(按我的偏好级别排序):

  • 删除已经存在的表,让alembic创建它们。这样,Alembic只需创建迁移中声明的表并更新其历史记录

  • 让Alembic相信它已经通过手动填充历史表应用了第一次迁移(我从来没有这样做过,但我认为这是可能的)。这样,它就不会再次尝试应用它

  • 从根迁移的
    upgrade()
    函数中删除
    create\u table
    指令(可能从
    grade()
    函数中删除
    drop\u table
    )。这样,Alembic将运行迁移,而不尝试创建已经存在的表,它应该可以工作。它还将记录其自身历史中应用的迁移

  • 在迁移中添加一个测试以仅在表不存在时创建该表,但在这种情况下,您将如何管理降级


  • 您已经在数据库上创建了多少个表?如果数量较少,则可以通读自动生成的alembic迁移脚本,并删除已创建的表的
    create_table
    条目。然后运行Upgrade在哪里可以找到脚本?您是在谈论修订脚本(在版本文件夹中)?我的问题是,alembic在运行sqlalchemy脚本之前创建了sqlalchemy中的所有表“尝试创建allready现有表时出错,即使我尝试在新创建的完全空的数据库上运行升级头,我的问题是我想控制alembic的操作。因此,我希望我的第一个修订版创建我想要的表(op.create_table)。即使在新的空数据库上运行alembic升级脚本,也会出现此错误。这让我得出结论,我激活了一些alembic选项,在这些修订脚本运行之前,该选项创建了我所有的sqlalchemy表,与我的修订脚本无关。谢谢,Base.metadata.create_all(引擎)就是问题所在。当我运行脚本时,它是否在没有alembic的情况下创建了我的表?Stackoverflow告诉我需要等待15个小时才能授予赏金,所以如果我忘记了明天,请随时记住我;-)@感谢您在编辑部分提出的建议(对Base.metadata.create_all(engine)行进行注释)。
    def upgrade():
        ...
        op.create_table('Data',
        ...