Multiple Databases with Binds
*****************************

SQLAlchemy can connect to more than one database at a time. It refers
to different engines as "binds". Flask-SQLAlchemy simplifies how binds
work by associating each engine with a short string, a "bind key", and
then associating each model and table with a bind key. The session
will choose what engine to use for a query based on the bind key of
the thing being queried. If no bind key is given, the default engine
is used.


Configuring Binds
=================

The default bind is still configured by setting
"SQLALCHEMY_DATABASE_URI", and "SQLALCHEMY_ENGINE_OPTIONS" for any
engine options. Additional binds are given in "SQLALCHEMY_BINDS", a
dict mapping bind keys to engine URLs. To specify engine options for a
bind, the value can be a dict of engine options with the ""url"" key,
instead of only a URL string.

   SQLALCHEMY_DATABASE_URI = "postgresql:///main"
   SQLALCHEMY_BINDS = {
       "meta": "sqlite:////path/to/meta.db",
       "auth": {
           "url": "mysql://localhost/users",
           "pool_recycle": 3600,
       },
   }


Defining Models and Tables with Binds
=====================================

Flask-SQLAlchemy will create a metadata and engine for each configured
bind. Models and tables with a bind key will be registered with the
corresponding metadata, and the session will query them using the
corresponding engine.

To set the bind for a model, set the "__bind_key__" class attribute.
Not setting a bind key is equivalent to setting it to "None", the
default key.

   class User(db.Model):
       __bind_key__ = "auth"
       id = db.Column(db.Integer, primary_key=True)

Models that inherit from this model will share the same bind key, or
can override it.

To set the bind for a table, pass the "bind_key" keyword argument.

   user_table = db.Table(
       "user",
       db.Column("id", db.Integer, primary_key=True),
       bind_key="auth",
   )

Ultimately, the session looks up the bind key on the metadata
associated with the model or table. That association happens during
creation. Therefore, changing the bind key after creating a model or
table will have no effect.


Accessing Metadata and Engines
==============================

You may need to inspect the metadata or engine for a bind. Note that
you should execute queries through the session, not directly on the
engine.

The default engine is "SQLAlchemy.engine", and the default metadata is
"SQLAlchemy.metadata". "SQLAlchemy.engines" and "SQLAlchemy.metadatas"
are dicts mapping all bind keys.


Creating and Dropping Tables
============================

The "create_all()" and "drop_all()" methods operate on all binds by
default. The "bind_key" argument to these methods can be a string or
"None" to operate on a single bind, or a list of strings or "None" to
operate on a subset of binds. Because these methods access the
engines, they must be called inside an application context.

   # create tables for all binds
   db.create_all()

   # create tables for the default and "auth" binds
   db.create_all(bind_key=[None, "auth"])

   # create tables for the "meta" bind
   db.create_all(bind_key="meta")

   # drop tables for the default bind
   db.drop_all(bind_key=None)
