Обмен моделями sqlalchemy между флягой и другими приложениями

У меня есть работающее приложение Flask, которое настроено в соответствии с сочетанием лучших практик, которые мы нашли в Интернете и в книге Мигеля Гринберга "Flask Web Development".

Теперь нам нужно второе приложение Python, которое НЕ является веб-приложением, и которому необходим доступ к тем же моделям, что и к приложению Flask. Мы хотели повторно использовать одни и те же модели курса, чтобы оба приложения могли извлечь выгоду из общего кода.

Мы удалили зависимости от расширения flask-sqlalchemy (которое мы использовали раньше, когда у нас было только приложение Flask). И заменил его наSQLalchemy Декларативное расширение описано здесь, что немного проще (Flask-SQLalchemy добавляет несколько специфических вещей в стандартную SQLAlchemy)

В соответствии с примером мы создали файл database.py в корне. В нашем случае есть две вещи, отличающиеся от примера декларативного расширения: я помещаю движок и сессию в класс, потому что все наши модели используют db.session вместо db_session, и я передаю словарь со значениями конфигурации вв этом(), так что я могу повторно использовать этот database.py из Flask, а также из другого приложения, используя другую конфигурацию. это выглядит так:

from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base


class Database(object):

    def __init__(self, cfg):
        self.engine = create_engine(cfg['SQLALCHEMY_DATABASE_URI'], convert_unicode=True)
        self.session = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=self.engine))

    class Model(object):
        pass

Base = declarative_base()

Итак, теперь мы подошли к актуальной проблеме. Flask создает словарь-объект, содержащий параметры конфигурации, и добавляет их в качестве свойства к экземпляру приложения. Он загружает их изпапка экземпляра,config.py в корне сайта и из переменных окружения. Мне нужно передать словарь конфигурации из Flask, поэтому мне нужно, чтобы Flask ПЕРВЫЙ загрузил и собрал конфигурацию, после чего инициализировал базу данных и имел (настроенный) объект db в корне файла приложения. Тем не менее, мы следуемШаблон фабрики приложений, поэтому мы можем использовать разные конфигурации для разных ситуаций (тестирование, производство, разработка).

Это означает, что нашapp/__init__.py выглядит примерно так (упрощенно):

from flask import Flask
from database import Database
from flask.ext.mail import Mail
from flask_bcrypt import Bcrypt
from config import config

mail = Mail()
bcrypt = Bcrypt()


def create_app(config_name):

    app = Flask(__name__, instance_relative_config=True)

    if not config_name:
        config_name = 'default'
    app.config.from_object(config[config_name])
    app.config.from_pyfile('config.py')
    config[config_name].init_app(app)

    db = Database(app.config)

    mail.init_app(app)
    bcrypt.init_app(app)

    @app.teardown_appcontext
    def shutdown_session(exception=None):
        db.session.remove()

    from main import main as main_blueprint
    app.register_blueprint(main_blueprint)

    return app

Но база данных (которую модели импортируют из ..) теперь должна находиться внутри функции create_app (), потому что именно там Flask загружает конфигурацию. Если бы я создал экземпляр объекта db вне функции create_app (), он будет импортирован из моделей, но он не настроен!

Примерная модель выглядит следующим образом, и, как вы можете видеть, она ожидает «db» в корне приложения:

from . base_models import areas
from sqlalchemy.orm import relationship, backref
from ..utils.helper_functions import newid
from .. import db


class Areas(db.Model, areas):
    """Area model class.
    """
    country = relationship("Countries", backref=backref('areas'))

    def __init__(self, *args, **kwargs):
        self.area_id = newid()
        super(Areas, self).__init__(*args, **kwargs)

    def __str__(self):
        return u"{}".format(self.area_name).encode('utf8')

    def __repr__(self):
        return u"<Area: '{}'>".format(self.area_name).encode('utf8')

Итак, мой вопрос, как я могу иметь экземпляр db, который можно настроить внешне (либо с помощью Flask, либо другого приложения), и при этом использовать шаблон фабрики приложений?

редактировать: Пример кода был неверным, он имел импорт для Flask-SQLalchemy, который был заменен наfrom database import Database, Извините за путаницу.

Ответы на вопрос(4)

Ваш ответ на вопрос