代码之家  ›  专栏  ›  技术社区  ›  Florian H

防止alembic自动生成表

  •  0
  • Florian H  · 技术社区  · 7 年前

    我是如此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创建):

    revision = 'bb1d39b7eee1'
    down_revision = None
    branch_labels = None
    depends_on = None
    
    
    def upgrade():
        # ### commands auto generated by Alembic - please adjust! ###
        op.create_table('Data',
        sa.Column('id', sa.Integer(), nullable=False),
        sa.Column('name', sa.String(), nullable=False),
        sa.PrimaryKeyConstraint('id'),
        schema='schema'
        )
        ...
    

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

    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不要自动创建任何表,而只运行我创建的脚本?

    1 回复  |  直到 7 年前
        1
  •  3
  •   Tryph    7 年前

    Data 表格:

    def upgrade():
        ...
        op.create_table('Data',
        ...
    

    所以如果你的 表已经存在,因为您已经手动创建了它,所以出现错误是正常的。

    编辑: Base.metadata.create_all(engine) 数据库初始化脚本中的行。我怀疑是它造成了这些表格。 我从未见过alembic在运行迁移之前创建表(这是迁移创建表的工作),如果它不能解决您的问题,我认为问题不是来自alembic。


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

    down_revision None )头一个。 在每次应用的迁移中,它还更新其历史记录表以反映数据库状态。

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

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

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

    3. create_table 来自根迁移的指令 upgrade() 功能(可能还有 drop_table downgrade() 函数)。这样,Alembic就可以运行迁移,而不必尝试创建已经存在的表,而且应该可以工作。它还将记录在自己的历史中应用的迁移。

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