title: Share sqlalchemy models between flask and other apps
body: <p>I have a running Flask application that is set up according to a combination of best practices we found online and in Miguel Grinberg's "Flask Web Development" book.</p>
  
  <p>We now need a second Python application, that is NOT a web app, and that needs access to the same models as the Flask application. We wanted to re-use the same models ofcourse, so both apps can benefit from the shared code.</p>
  
  <p>We have removed dependencies on the flask-sqlalchemy extention (which we used before, when we had just the Flask application). And replaced it with the <a href="http://flask.pocoo.org/docs/0.10/patterns/sqlalchemy/">SQLalchemy Declarative extension described here</a>, which is a bit simpler (<a href="http://derrickgilland.com/posts/demystifying-flask-sqlalchemy/">Flask-SQLalchemy adds a few specific things to standard SQLAlchemy</a>)</p>
  
  <p>In line with the example we have created a database.py file in the root. In our case there are two things different from the Declarative extension example: I put the engine and session in a class, because all of our models use db.session, instead of db_session, and I pass a dictionary with configuration values to the <strong>init()</strong>, so that I can re-use this database.py from both Flask as well as another application, using a different configuration. it looks like this:</p>
  
  <pre><code>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()
  </code></pre>
  
  <p>So now we come to the actual problem. Flask creates a dictionary-like object containing configuration options, and adds them as a property to the app-instance. It loads them from an <a href="http://flask.pocoo.org/docs/0.10/config/#instance-folders">instance folder</a>, a <a href="http://flask.pocoo.org/docs/0.10/config/#configuring-from-files">config.py</a> in the root of the site and from environment variables. I need to pass in the configuration dictionary from Flask, so I need Flask to FIRST load and assemble the configuration, and after that initialise the database, and have a (configured) db object in the root of the app file. However, we follow the <a href="http://flask.pocoo.org/docs/0.10/patterns/appfactories/">Application factory pattern</a>, so we can use different configurations for different situations (test, production, development).  </p>
  
  <p>This means our <code>app/__init__.py</code> looks something like this (simplified):</p>
  
  <pre><code>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
  </code></pre>
  
  <p>But the db (that the models import from ..), now needs to be inside the create_app() function, because that's where Flask loads the configuration. If I would instantiate the db object outside of the create_app() function, it will be importable from the models, but it is not configured!</p>
  
  <p>an example model looks like this, and as you can see, it expects a "db" in the root of the app:</p>
  
  <pre><code>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"&lt;Area: '{}'&gt;".format(self.area_name).encode('utf8')
  </code></pre>
  
  <p>So my question is, how can I have a db instance that can be configured externally (by either Flask or another app), and still use the Application Factory Pattern? </p>
  
  <p><strong>edit:</strong> The code-example was incorrect, it had an import for Flask-SQLalchemy which was replaced by <code>from database import Database</code>. Sorry for any confusion.</p>