Skip to main content
 首页 » 编程设计

python之Alembic 试图删除我的表

2025年05月04日21kerrycode

这里是 Alembic 初学者。我在 Alembic 尝试删除已创建的表时遇到了一些问题。我不知道发生了什么。现在我有一个看起来像这样的数据库:

如果我运行 alembic upgrade head ,我会得到这样的结果:

INFO  [alembic.runtime.migration] Context impl PostgresqlImpl. 
INFO  [alembic.runtime.migration] Will assume transactional DDL. 

如果我运行 alembic history ,我会得到这个正确的结果:

c2659db918a9 -> 765c30f7078c (head), creat table views 
c4a0cac54f89 -> c2659db918a9, Made last_update not null for all tables 
19dd9f3d1d16 -> c4a0cac54f89, Added last_update field defaulted to now 
77c03ebb393b -> 19dd9f3d1d16, Added indexes to each table 
0737825277d8 -> 77c03ebb393b, Change foreign key columns to non-nullable 
5eb3c5f7f599 -> 0737825277d8, Rename a column in daily_etf_underlying table 
0da0b2a43172 -> 5eb3c5f7f599, Add extra_info column to daily_etf_underlying 
c181fe8bcfa9 -> 0da0b2a43172, Make daily_etf id columns nullable 
8fba2675104b -> c181fe8bcfa9, added fixing table 
074563d69c3b -> 8fba2675104b, Modify daily_etf tables 
2c9de57e43f0 -> 074563d69c3b, Add fund_family columns 
80de6fb0a104 -> 2c9de57e43f0, Modify daily_etf table 
a970af9bb117 -> 80de6fb0a104, Add daily_etf_basket, daily_etf_fx_forward tables 
<base> -> a970af9bb117, Add daily_etf table 

但是如果我运行 alembic revision --autogenerate -m "<>" ,我就明白了!

alembic revision --autogenerate -m "Raw fidessa client trade table" 
INFO  [alembic.runtime.migration] Context impl PostgresqlImpl. 
INFO  [alembic.runtime.migration] Will assume transactional DDL. 
INFO  [alembic.ddl.postgresql] Detected sequence named 'daily_etf_fx_forward_id_seq' as owned by integer column 'daily_etf_fx_forward(id)', assuming SERIAL and omitting 
INFO  [alembic.autogenerate.compare] Detected removed table 'daily_etf_fx_forward' 
INFO  [alembic.autogenerate.compare] Detected removed table 'daily_etf' 
INFO  [alembic.ddl.postgresql] Detected sequence named 'daily_fx_fixing_rate_id_seq' as owned by integer column 'daily_fx_fixing_rate(id)', assuming SERIAL and omitting 
INFO  [alembic.autogenerate.compare] Detected removed table 'daily_fx_fixing_rate' 
INFO  [alembic.ddl.postgresql] Detected sequence named 'daily_etf_underlying_id_seq' as owned by integer column 'daily_etf_underlying(id)', assuming SERIAL and omitting 
INFO  [alembic.autogenerate.compare] Detected removed table 'daily_etf_underlying' 
Generating C:\dev\Projects\stark_database\stark_database\migrations\versions\86174c06e59e_raw_fidessa_client_trade_table.py ... done 

我的自动生成文件只是试图删除我所有的表:(

def upgrade(): 
    # ### commands auto generated by Alembic - please adjust! ### 
    op.drop_table('daily_fx_fixing_rate') 
    op.drop_table('daily_etf_underlying') 
    op.drop_table('daily_etf') 
    op.drop_table('daily_etf_fx_forward') 
    # ### end Alembic commands ### 

这是怎么回事?为什么 alembic 试图删除所有内容?

感谢您的帮助。

编辑:alembic.ini:

[alembic] 
script_location = migrations 
sqlalchemy.url = postgresql://stark_admin:hpt@localhost/stark 

env.py 就是 alembic init alembic 的教科书

请您参考如下方法:

我想通了。 元数据 对象不正确。

对于阅读的人,

确保您在 target_metadata = metadata 中有正确的metadata。如果数据库中已有一些表,并且按照 Ilja 在评论中建议的那样提供新的 metadata 或 None 元数据,您将看到此行为,因为 alembic 知道基于在那个元数据上,那些表不应该在数据库中,所以它会尝试删除那些。

此外,通常您会在不同的文件中为 SQLAlchemy 设置类。为此,您必须确保在所有文件中使用相同的 metadata 或 Base 实例。否则,您将得到这种不检测表或尝试删除现有表的行为。

这是后一种情况的例子:

假设我有这样的结构

database 
    /migrations 
        /versions 
            1348ht31r3_first_migration.py 
        env.py 
        README 
        script.py.mako 
    /models 
        __init__.py 
        a_class.py 

在 __init__.py 中,我执行典型的 declarative_base():

# __init__.py 
from sqlalchemy import create_engine 
from sqlalchemy.ext.declarative import declarative_base 
 
Base = declarative_base() 
engine = create_engine('url') 

然后在 a_class.py 中,我的模型类的父类是 __init__.py

中的 Base
from datetime import datetime 
 
from sqlalchemy import Column, Integer, String, Float 
from sqlalchemy import Date, DateTime 
from sqlalchemy import ForeignKey 
from sqlalchemy.dialects.postgresql import JSONB 
from sqlalchemy.orm import relationship 
 
from stark_database.models import Base 
 
 
class AClass(Base): 
    __tablename__ = 'a_class' 
    id = Column(Integer, primary_key=True) 
    insert_date = Column(Date) 
    symbol = Column(String) 
    pnu = Column(Float) 
    projected_shares_outstanding = Column(Float) 
    shares_outstanding = Column(Float) 
    projected_nav = Column(Float) 
    nav = Column(Float) 
    basket_cash_per_currency = Column(JSONB) 
    fund_cash_per_currency = Column(JSONB) 
    info_type = Column(String) 
    fund_family = Column(String) 
    last_updated = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now) 

这是正确的,但在 env.py 中,您必须确保导入基类和模型。

from __future__ import with_statement 
 
import os 
import sys 
from logging.config import fileConfig 
 
from alembic import context 
from sqlalchemy import engine_from_config, pool 
 
# DO NOT DELETE THIS LINE.  
from database.models import Base, a_class 

这不是 alembic 的东西,但在我看来它有点像 python 陷阱。

希望这对您有所帮助。