How to use flask-migrate with other declarative_bases

I am trying to implement python-social-auth in Flask. I guessed tons of kinks while trying to interpret 4 textbooks and a complete flask book at the same time, and I feel like I've reached my dead end with Flask-migrate.

I am currently using the following code to create the tables necessary for python-social-auth to work in flask-sqlalchemy environment.

from social.apps.flask_app.default import models
models.PSABase.metadata.create_all(db.engine)

Now they explicitly use some form of their own base, not related to my actual db object. This, in turn, causes Flask-Migrate to completely skip these tables and delete them during migration. Now, obviously, I can remove these db drops from each delete, but I can imagine that this is one of those things that will be forgotten at some point, and suddenly I no longer have OAuth connections.

I got this solution to work using (and modifying) the manage.py-syncdb command suggested by python-social-auth Flash example

Miguel Greenberg, author of Flask-Migrate magazine, answers here , which seems to be very similar to mine.

The closest I could find when the stack overflowed was this one , but it did not shed too much light on the whole thing for me, and the answer was never accepted (and I can not get it to work, I tried several times)

For reference, here is my manage.py:

#!/usr/bin/env python

from flask.ext.script import Server, Manager, Shell
from flask.ext.migrate import Migrate, MigrateCommand


from app import app, db

manager = Manager(app)
manager.add_command('runserver', Server())
manager.add_command('shell', Shell(make_context=lambda: {
    'app': app,
    'db_session': db.session
}))

migrate = Migrate(app, db)
manager.add_command('db', MigrateCommand)

@manager.command
def syncdb():
    from social.apps.flask_app.default import models
    models.PSABase.metadata.create_all(db.engine)
    db.create_all()

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

And to clarify, the db init / migrate / upgrade commands only create my user table (and its migration), but not social, and the syncdb command works for python-social-auth tables.

github, Flask-Migrate, , PSABase, db-, Migrate.

.

( , . , , , , , . - SO, , )

+4
3

, , SQLAlchemy. PSA SQLAlchemy, Flask-SQLAlchemy.

Flask-Migrate , Flask-SQLAlchemy, db, , , PSA, Flask-SQLAlchemy.

, , , , Flask-Migrate/Alembic PSA db , .

, Alembic . include_object env.py, . , Alembic , , script. False, PSA, True .

. , , , , PSA Alembic.

, , , . Alembic , script, . , , , , , , -, , , Alembic script.

, include_object, . .

+2

Miguel . github, , , Alembic bitbucket, .

, almb.py Alembic:

from sqlalchemy import engine_from_config, pool, MetaData

[...]

# add your model MetaData object here
# for 'autogenerate' support
# from myapp import mymodel
# target_metadata = mymodel.Base.metadata
from flask import current_app
config.set_main_option('sqlalchemy.url',
                       current_app.config.get('SQLALCHEMY_DATABASE_URI'))

def combine_metadata(*args):
    m = MetaData()
    for metadata in args:
        for t in metadata.tables.values():
            t.tometadata(m)
    return m

from social.apps.flask_app.default import models

target_metadata = combine_metadata(
    current_app.extensions['migrate'].db.metadata,
    models.PSABase.metadata)

.

+3

: -

, db

db = SQLAlchemy()
app['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:' + POSTGRES_PASSWORD + '@localhost/Flask'
db.init_app(app)

class User(db.Model):
    pass

Base = declarative_base()
uri = 'postgresql://postgres:' + POSTGRES_PASSWORD + '@localhost/Flask'
engine = create_engine(uri)
metadata = MetaData(engine)
Session = sessionmaker(bind=engine)
session = Session()

class Address(Base):
    pass

Since you created the user with db.Model, you can use flask migrate for User and class Address used Base, which handles retrieving a pre-existing table from the database.

0
source

Source: https://habr.com/ru/post/1627224/


All Articles