Alembic trying to delete my tables

橙三吉。 提交于 2019-12-11 04:49:32

问题


Alembic beginner here. I'm having some issues with Alembic trying to delete my tables that are already created. I have no idea what is going on. Right now I have a database that looks like this:

If I run alembic upgrade head, I get this as my result:

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

If I run alembic history, I get this result, which is correct:

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

But if I run alembic revision --autogenerate -m "<>", I get this!

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

And my autogenerated file is just trying to remove all my tables :(

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 ###

What is going on here? Why is alembic trying to delete everything?

Thanks for your help.

EDIT: alembic.ini:

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

env.py is exactly textbook to alembic init alembic


回答1:


I figured out. The metadata object was incorrect.

For those reading,

Make sure you have the correct metadata in target_metadata = metadata. If you have some tables already in the database and you supply a new metadata or a None metadata as Ilja suggested in the comments, you will see this behavior because alembic knows that based on that metadata, those tables should not be in the database, so it will try to delete those.

Moreover, typically you will have classes in different files for SQLAlchemy. For this to work, you have to make sure that you are using the same metadata or Base instance across the files. Otherwise, you will get this behavior of not detecting tables or trying to delete existing tables.

Here's an example of the latter situation:

Suppose I have a structure like

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

In __init__.py, I do the typical declarative_base():

# __init__.py
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()
engine = create_engine('url')

And then in a_class.py, I have my model class whose parent class is the Base from __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)

This is correct, but in env.py, you have to make sure you import the Base class and the model.

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

This isn't an alembic thing but it's a bit of a python gotcha in my opinion.

Hope this helps.



来源:https://stackoverflow.com/questions/45695008/alembic-trying-to-delete-my-tables

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!