To use oslo.db in a project:
Session handling is achieved using the oslo_db.sqlalchemy.enginefacade system. This module presents a function decorator as well as a context manager approach to delivering Session as well as Connection objects to a function or block.
Both calling styles require the use of a context object. This object may be of any class, though when used with the decorator form, requires special instrumentation.
The context manager form is as follows:
from oslo_db.sqlalchemy import enginefacade
class MyContext(object):
"User-defined context class."
def some_reader_api_function(context):
with enginefacade.reader.using(context) as session:
return session.query(SomeClass).all()
def some_writer_api_function(context, x, y):
with enginefacade.writer.using(context) as session:
session.add(SomeClass(x, y))
def run_some_database_calls():
context = MyContext()
results = some_reader_api_function(context)
some_writer_api_function(context, 5, 10)
The decorator form accesses attributes off the user-defined context directly; the context must be decorated with the oslo_db.sqlalchemy.enginefacade.transaction_context_provider() decorator. Each function must receive the context as the first positional argument:
from oslo_db.sqlalchemy import enginefacade
@enginefacade.transaction_context_provider
class MyContext(object):
"User-defined context class."
@enginefacade.reader
def some_reader_api_function(context):
return context.session.query(SomeClass).all()
@enginefacade.writer
def some_writer_api_function(context, x, y):
context.session.add(SomeClass(x, y))
def run_some_database_calls():
context = MyContext()
results = some_reader_api_function(context)
some_writer_api_function(context, 5, 10)
The scope of transaction and connectivity for both approaches is managed transparently. The configuration for the connection comes from the standard oslo_config.cfg.CONF collection. Additional configurations can be established for the enginefacade using the oslo_db.sqlalchemy.enginefacade.configure() function, before any use of the database begins:
from oslo_db.sqlalchemy import enginefacade
enginefacade.configure(
sqlite_fk=True,
max_retries=5,
mysql_sql_mode='ANSI'
)
from oslo.db import models
class ProjectSomething(models.TimestampMixin,
models.ModelBase):
id = Column(Integer, primary_key=True)
...
from oslo.config import cfg
from oslo.db import api as db_api
_BACKEND_MAPPING = {'sqlalchemy': 'project.db.sqlalchemy.api'}
IMPL = db_api.DBAPI.from_config(cfg.CONF, backend_mapping=_BACKEND_MAPPING)
def get_engine():
return IMPL.get_engine()
def get_session():
return IMPL.get_session()
# DB-API method
def do_something(somethind_id):
return IMPL.do_something(somethind_id)