Working with the same metadata in Multiple Databases
In some applications, it may be desirable for there to be multiple instances of a database all sharing the same metadata (for example, if each user gets a new database for each user session). This recipe describes the basic technique using Elixir to manage multiple databases with only one metadata.
The Recipe
By default, Elixir creates a session and metadata for the context of the application. In this recipe, we continue to use the application-wide metadata, but disable the application-wide session and instead create two session instances, each connected to a distinct engine. This recipe has been tested in Elixir 0.5.2 and 0.6.0 using SQLAlchemy 0.4.6.
from sqlalchemy.orm import scoped_session, sessionmaker from sqlalchemy import create_engine import elixir import logging log = logging.getLogger('demo') # I want to create any number of databases that all use the same schema (metadata). # first, I have to make sure that Elixir doesn't automatically bind the various # classes to the default session. __session__ = None # Here's an example metadata... keeping it simple elixir.options_defaults['shortnames'] = True class Person(elixir.Entity): name = elixir.Field(elixir.Unicode(256), required=True) def __repr__(self): return 'Person(name="%s")' % self.name elixir.setup_all() # Since __session__ is None, Person should not have a query attribute assert not hasattr(Person, 'query') # For this example, I'll just use two engines/sessions, a & b. a_engine = create_engine('sqlite:///', echo=True) a_session = scoped_session(sessionmaker(autoflush=True, transactional=True, bind=a_engine)) b_engine = create_engine('sqlite:///', echo=True) b_session = scoped_session(sessionmaker(autoflush=True, transactional=True, bind=b_engine)) # now that I've got two sessions, let's create the schema in each. elixir.create_all(a_engine) elixir.create_all(b_engine) # get all of the people in a_session assert a_session.query(Person).all() == [] # get all of the people in b_session assert b_session.query(Person).all() == [] # create a new person in a_session a_person = Person(name=u"George Washington") a_session.save(a_person) a_session.commit() a_session.clear() # create a new person in b_session b_person = Person(name=u"Thomas Jefferson") b_session.save(b_person) b_session.commit() b_session.clear() # get all of the people in a_session a_people = a_session.query(Person).all() print 'session a contains', a_people # get all of the people in b_session b_people = b_session.query(Person).all() print 'session b contains', b_people
