Flask-Migrate не создает таблицы

У меня есть следующие модели в файле listpull/models.py:

from datetime import datetime

from listpull import db


class Job(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    list_type_id = db.Column(db.Integer, db.ForeignKey('list_type.id'),
                             nullable=False)
    list_type = db.relationship('ListType',
                                backref=db.backref('jobs', lazy='dynamic'))
    record_count = db.Column(db.Integer, nullable=False)
    status = db.Column(db.Integer, nullable=False)
    sf_job_id = db.Column(db.Integer, nullable=False)
    created_at = db.Column(db.DateTime, nullable=False)
    compressed_csv = db.Column(db.LargeBinary)

    def __init__(self, list_type, created_at=None):
        self.list_type = list_type
        if created_at is None:
            created_at = datetime.utcnow()
        self.created_at = created_at

    def __repr__(self):
        return '<Job {}>'.format(self.id)


class ListType(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), unique=True, nullable=False)

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return '<ListType {}>'.format(self.name)

Я вызываю ./run.py init, затем ./run.py migrate, затем ./run.py upgrade, и вижу файл миграции, но его пустой:

"""empty message

Revision ID: 5048d48b21de
Revises: None
Create Date: 2013-10-11 13:25:43.131937

"""

# revision identifiers, used by Alembic.
revision = '5048d48b21de'
down_revision = None

from alembic import op
import sqlalchemy as sa


def upgrade():
    ### commands auto generated by Alembic - please adjust! ###
    pass
    ### end Alembic commands ###


def downgrade():
    ### commands auto generated by Alembic - please adjust! ###
    pass
    ### end Alembic commands ###

run.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from listpull import manager
manager.run()

listpull/__ __ INIT. Ру

# -*- coding: utf-8 -*-
# pylint: disable-msg=C0103

""" listpull module """

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.script import Manager
from flask.ext.migrate import Migrate, MigrateCommand
from mom.client import SQLClient
from smartfocus.restclient import RESTClient


app = Flask(__name__)
app.config.from_object('config')

db = SQLAlchemy(app)

migrate = Migrate(app, db)

manager = Manager(app)
manager.add_command('db', MigrateCommand)

mom = SQLClient(app.config['MOM_HOST'],
                app.config['MOM_USER'],
                app.config['MOM_PASSWORD'],
                app.config['MOM_DB'])

sf = RESTClient(app.config['SMARTFOCUS_URL'],
                app.config['SMARTFOCUS_LOGIN'],
                app.config['SMARTFOCUS_PASSWORD'],
                app.config['SMARTFOCUS_KEY'])

import listpull.models
import listpull.views

UPDATE

Если я запустил оболочку через ./run.py shell, а затем сделаю from listpull import * и позвоню db.create_all(), я получаю схему:

[email protected]:~/code/nhs-listpull$ sqlite3 app.db 
-- Loading resources from /Users/mark.richman/.sqliterc
SQLite version 3.7.12 2012-04-03 19:43:07
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .schema
CREATE TABLE job (
    id INTEGER NOT NULL, 
    list_type_id INTEGER NOT NULL, 
    record_count INTEGER NOT NULL, 
    status INTEGER NOT NULL, 
    sf_job_id INTEGER NOT NULL, 
    created_at DATETIME NOT NULL, 
    compressed_csv BLOB, 
    PRIMARY KEY (id), 
    FOREIGN KEY(list_type_id) REFERENCES list_type (id)
);
CREATE TABLE list_type (
    id INTEGER NOT NULL, 
    name VARCHAR(80) NOT NULL, 
    PRIMARY KEY (id), 
    UNIQUE (name)
);
sqlite> 

К сожалению, миграция по-прежнему не работает.

Ответ 1

Когда вы вызываете команду migrate Flask-Migrate (или фактически Alembic под ней), вы будете смотреть на свой models.py и сравнивать это с тем, что на самом деле находится в вашей базе данных.

Тот факт, что у вас есть пустая миграция script, предлагает вам обновить вашу базу данных, чтобы она соответствовала вашей модели, с помощью другого метода, который находится вне элемента управления Flask-Migrate, может быть, вызвав флажок-SQLAlchemy db.create_all().

Если у вас нет каких-либо ценных данных в вашей базе данных, откройте оболочку Python и вызовите db.drop_all(), чтобы удалить его, затем повторите попытку автоматической миграции.

UPDATE. Я установил ваш проект здесь и подтвердил, что миграции работают нормально для меня:

(venv)[[email protected] nhs-listpull]$ ./run.py db init
  Creating directory /home/miguel/tmp/mark/nhs-listpull/migrations...done
  Creating directory /home/miguel/tmp/mark/nhs-listpull/migrations/versions...done
  Generating /home/miguel/tmp/mark/nhs-listpull/migrations/script.py.mako...done
  Generating /home/miguel/tmp/mark/nhs-listpull/migrations/env.pyc...done
  Generating /home/miguel/tmp/mark/nhs-listpull/migrations/env.py...done
  Generating /home/miguel/tmp/mark/nhs-listpull/migrations/README...done
  Generating /home/miguel/tmp/mark/nhs-listpull/migrations/alembic.ini...done
  Please edit configuration/connection/logging settings in
  '/home/miguel/tmp/mark/nhs-listpull/migrations/alembic.ini' before
  proceeding.
(venv)[[email protected] nhs-listpull]$ ./run.py db migrate
INFO  [alembic.migration] Context impl SQLiteImpl.
INFO  [alembic.migration] Will assume non-transactional DDL.
INFO  [alembic.autogenerate] Detected added table 'list_type'
INFO  [alembic.autogenerate] Detected added table 'job'
  Generating /home/miguel/tmp/mark/nhs-
  listpull/migrations/versions/48ff3456cfd3_.py...done

Попробуйте новую проверку, я думаю, что ваша настройка верна.

Ответ 2

Обязательно импортируйте Модели в файл manage.py (или файл с экземпляром migrate). Вы должны импортировать модели в файл, даже если вы явно не используете их. Alembic нуждается в этих импортерах для миграции и создания таблиц в базе данных. Например:

# ... some imports ...
from api.models import User, Bucketlist, BucketlistItem # Import the models

app = create_app('dev')
manager = Manager(app)
migrate = Migrate(app, db)

manager.add_command('db', MigrateCommand)

# ... some more code here ...

if __name__ == "__main__":
    manager.run()
    db.create_all()

Ответ 3

Я столкнулся с подобной проблемой. Я хотел бы поделиться своим решением для тех, кто сталкивается с этой нитью. Для меня у меня были модели в пакете. Например, модели /user.py и я попробовал from app.models import *, который ничего не обнаружил при переносе. Однако, если я изменил импорт на from app.models import user, это нормально, потому что мой проект молод, но поскольку у меня есть больше моделей, то массовый импорт будет предпочтительнее.

Ответ 4

Для тех, кто приходит, кто сталкивается с этим, моя проблема заключалась в том, что

db.create_all()

в файле моей основной фляги который создал новую таблицу без знания alembic

Просто прокомментируйте это или удалите его полностью, чтобы он не смешивался с будущими миграциями.

но в отличие от предложения @Miguel вместо того, чтобы отбрасывать всю базу данных (у меня была важная информация), я смог ее исправить, удалив новую таблицу, созданную Flask SQLAlchemy, а затем выполнив миграцию.

и на этот раз alembic обнаружил новую таблицу и создал надлежащую миграцию script

Ответ 5

У меня была та же самая проблема, но другая проблема вызвала это. Рабочий процесс Flask-migrate состоит из двух последовательных команд:

flask db migrate

который генерирует миграцию и

flask db upgrade

который применяет миграцию. Я забыл запустить последнюю и попытался запустить следующую миграцию, не применяя предыдущую.

Ответ 6

Странно решить для меня: удаление баз данных и папок migrations. затем

>>> from app import db
>>> db.create_all()

После flask db init или python app.py db init а затем flask db migrate или python app.py db migrate. Ух, странно, но у меня это работает.