Flask-migrate: flask migrate not detecting models, dropping all tables

Created on 6 Jan 2016  ·  5Comments  ·  Source: miguelgrinberg/Flask-Migrate

Hi,

I have the following code for my migrate script :

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand

app = Flask(name)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + 'C:flaskDBcommBorn4.db'

db = SQLAlchemy(app)
import models

migrate = Migrate(app, db)

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

if name == 'main':
manager.run()

My application is in a single module, but my models are in models.py in the same folder as the application. When I run db migrate on the command line, I get the following :

"""initial migration 3

Revision ID: 2c8531e9a116
Revises: None
Create Date: 2016-01-06 12:16:00.315000

"""

revision identifiers, used by Alembic.

revision = '2c8531e9a116'
down_revision = None

from alembic import op
import sqlalchemy as sa

def upgrade():
### commands auto generated by Alembic - please adjust! ###
op.drop_table('entries')
op.drop_table('users')
### end Alembic commands ###

def downgrade():
### commands auto generated by Alembic - please adjust! ###
op.create_table('users',
sa.Column('id', sa.INTEGER(), nullable=False),
sa.Column('user_email', sa.VARCHAR(length=64), nullable=True),
sa.Column('user_name', sa.VARCHAR(length=64), nullable=True),
sa.Column('user_pass', sa.VARCHAR(length=128), nullable=True),
sa.Column('role_id', sa.INTEGER(), nullable=True),
sa.Column('communities', sa.VARCHAR(length=64), nullable=True),
sa.Column('articles_compared', sa.VARCHAR(length=64), nullable=True),
sa.Column('date_joined', sa.DATETIME(), nullable=True),
sa.ForeignKeyConstraint(['role_id'], [u'roles.id'], ),
sa.PrimaryKeyConstraint('id')
)

op.create_table('entries',
sa.Column('id', sa.INTEGER(), nullable=False),
sa.Column('title', sa.VARCHAR(length=64), nullable=True),
sa.Column('text', sa.VARCHAR(length=64), nullable=True),
sa.Column('user_id', sa.INTEGER(), nullable=True),
sa.Column('date_posted', sa.DATETIME(), nullable=True),
sa.ForeignKeyConstraint(['user_id'], [u'users.id'], ),
sa.PrimaryKeyConstraint('id')
)

### end Alembic commands ###

if name == 'main':
manager.run()

This is what models.py looks like :

'''
Created on Nov 26, 2014

@author: Ben
'''

from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import UserMixin
from sqlalchemy.orm import backref
from sqlalchemy.sql.schema import PrimaryKeyConstraint

alchemyDB = SQLAlchemy()

class User(UserMixin, alchemyDB.Model):
tablename = 'users'
id = alchemyDB.Column(alchemyDB.Integer, primary_key = True)
user_email = alchemyDB.Column(alchemyDB.String(64), unique = True, index = True)
user_name = alchemyDB.Column(alchemyDB.String(64), unique = True, index = True)
user_pass = alchemyDB.Column(alchemyDB.String(128))
role_id = alchemyDB.Column(alchemyDB.Integer, alchemyDB.ForeignKey('roles.id'))

class Entries(alchemyDB.Model):
'''
defines what an entry is. This includes text, links, images etc.
'''
tablename = 'entries'
id = alchemyDB.Column(alchemyDB.Integer, primary_key = True)
title = alchemyDB.Column(alchemyDB.String(64))
text = alchemyDB.Column(alchemyDB.String(64))
user_id = alchemyDB.Column(alchemyDB.Integer, alchemyDB.ForeignKey('users.id'))
date_posted = alchemyDB.Column(alchemyDB.DateTime)

So, it seems that the models are not being detected and all the tables in the database are dropped. What might I be doing wrong?

Most helpful comment

You are using a different db instance in models.py to create your models. I think because of this, the Flask app does not see the models, so it thinks they have been removed.

All 5 comments

You are using a different db instance in models.py to create your models. I think because of this, the Flask app does not see the models, so it thinks they have been removed.

Thanks Miguel! And thanks for the book! It has been really helpful.
On 6 Jan 2016 16:30, "Miguel Grinberg" [email protected] wrote:

You are using a different db instance in models.py to create your models.
I think because of this, the Flask app does not see the models, so it
thinks they have been removed.


Reply to this email directly or view it on GitHub
https://github.com/miguelgrinberg/Flask-Migrate/issues/94#issuecomment-169468968
.

@miguelgrinberg Sorry to reopen this issue, but I can't determine how to ensure my manage.py script is using the same database instance as my models. I'm extending the PyBossa project and am experiencing this same issues when using Flask-Migrate or straight alembic.

Base model: https://github.com/Scifabric/pybossa/blob/master/pybossa/model/__init__.py
Model example: https://github.com/Scifabric/pybossa/blob/master/pybossa/model/project.py
manage.py:

from flask import Flask
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand
from flask_sqlalchemy import SQLAlchemy
from pybossa.core import db


app = Flask(__name__)
app.config.from_object('settings_local')
#db = SQLAlchemy(app)
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)

if __name__ == '__main__':
    manager.run()

It seems like no matter how I define db, all of my tables still get dropped.

@Lythimus sqlalchemy uses introspection to figure out what the models of your application are. You need to make sure all your models are imported, even if they are not directly used, because any models that are not imported will no be detected, and then Alembic will think that is a model that was removed and needs its table dropped.

Check what you import when you run manage.py db and ensure all your models are loaded. Then you should be fine.

@miguelgrinberg Thanks so much. I'd tried importing all models directly using straight Alembic, but it wasn't working either because I wasn't setting my config or or I wasn't using db from pybossa.core. Either way, I got it going with this manage.py. Let me know if you accept tips 👍

from flask import Flask
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand
from flask_sqlalchemy import SQLAlchemy
from pybossa.core import db

from pybossa.model.auditlog import Auditlog
from pybossa.model.blogpost import Blogpost
from pybossa.model.category import Category
from pybossa.model.project import Project
from pybossa.model.result import Result
from pybossa.model.task import Task
from pybossa.model.task_run import TaskRun
from pybossa.model.user import User
from pybossa.model.webhook import Webhook


app = Flask(__name__)
app.config.from_object('settings_local')
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)

if __name__ == '__main__':
    manager.run()
Was this page helpful?
0 / 5 - 0 ratings