防止 alembic 自动生成表
Prevent alembic from autogenerating tables
我是 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 不要自动创建任何表,而只 运行 我创建的脚本?
您的迁移明确创建 Data
table:
def upgrade():
...
op.create_table('Data',
...
所以如果你的Data
table已经存在,因为你已经手动创建了它,那么出现错误是正常的。
编辑:
我不确定它何时执行,但您可能想尝试在数据库初始化脚本中注释 Base.metadata.create_all(engine)
行。我怀疑它会创建 tables。
我从未见过 alembic 在 运行 迁移之前创建 tables(这是迁移创建 tables 的工作),如果它不能解决您的问题,我认为问题是不是来自蒸馏器。
Alembic 旨在从一开始就管理您的数据库迁移,它并不假定您已经创建了 tables。
基本上它会创建一个 table 来保存应用于数据库的迁移历史记录。当您 运行 第一次升级时,还没有应用迁移,因此 Alembic 将尝试 运行 从根目录(其 down_revision
是 None
)开始的所有迁移升级到头一个。
在每次应用迁移时,它还会更新其历史记录 table 以反映数据库状态。
你可以(按我的喜好程度排序):
删除您已经存在的 table 并让 alembic 创建它们。这样,Alembic 只需创建在迁移中声明的 table 并更新其历史记录。
让 Alembic 相信它已经通过手动填充其历史记录应用了第一次迁移 table(我从未这样做过,但我认为这是可能的)。这样它就不会尝试再次应用它
从根迁移的 upgrade()
函数中删除 create_table
指令(可能还有 downgrade()
函数中的 drop_table
)。这样,Alembic 将 运行 迁移而不尝试创建已经存在的 table,它应该可以工作。它还会记录在其自己的历史记录中应用的迁移。
在您的迁移中添加一个测试以创建 table 仅当它尚不存在时,但在这种情况下您将如何管理降级?
我是 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 不要自动创建任何表,而只 运行 我创建的脚本?
您的迁移明确创建 Data
table:
def upgrade():
...
op.create_table('Data',
...
所以如果你的Data
table已经存在,因为你已经手动创建了它,那么出现错误是正常的。
编辑:
我不确定它何时执行,但您可能想尝试在数据库初始化脚本中注释 Base.metadata.create_all(engine)
行。我怀疑它会创建 tables。
我从未见过 alembic 在 运行 迁移之前创建 tables(这是迁移创建 tables 的工作),如果它不能解决您的问题,我认为问题是不是来自蒸馏器。
Alembic 旨在从一开始就管理您的数据库迁移,它并不假定您已经创建了 tables。
基本上它会创建一个 table 来保存应用于数据库的迁移历史记录。当您 运行 第一次升级时,还没有应用迁移,因此 Alembic 将尝试 运行 从根目录(其 down_revision
是 None
)开始的所有迁移升级到头一个。
在每次应用迁移时,它还会更新其历史记录 table 以反映数据库状态。
你可以(按我的喜好程度排序):
删除您已经存在的 table 并让 alembic 创建它们。这样,Alembic 只需创建在迁移中声明的 table 并更新其历史记录。
让 Alembic 相信它已经通过手动填充其历史记录应用了第一次迁移 table(我从未这样做过,但我认为这是可能的)。这样它就不会尝试再次应用它
从根迁移的
upgrade()
函数中删除create_table
指令(可能还有downgrade()
函数中的drop_table
)。这样,Alembic 将 运行 迁移而不尝试创建已经存在的 table,它应该可以工作。它还会记录在其自己的历史记录中应用的迁移。在您的迁移中添加一个测试以创建 table 仅当它尚不存在时,但在这种情况下您将如何管理降级?