Alembic试图删除我的表格

时间:2017-08-15 14:29:08

标签: python sqlalchemy alembic

Alembic初学者在这里。我遇到了Alembic试图删除已经创建的表的一些问题。我不知道发生了什么事。现在我有一个如下所示的数据库:

enter image description here

如果我运行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

的教科书

1 个答案:

答案 0 :(得分:4)

我发现了。 metadata对象不正确。

对于那些阅读,

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

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

以下是后一种情况的一个例子:

假设我有一个类似

的结构
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

的基类
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。

希望这有帮助。