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)
Note
The context.session and context.connection attributes must be accessed within the scope of an appropriate writer/reader block (either the decorator or contextmanager approach). An AttributeError is raised otherwise.
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)
Available extensions for oslo_db.migration.
Extension to provide alembic features.
param engine: | SQLAlchemy engine instance for a given database |
---|---|
type engine: | sqlalchemy.engine.Engine |
param migration_config: | |
Stores specific configuration for migrations | |
type migration_config: | |
dict |
Extension to provide sqlalchemy-migrate features.
param migration_config: | |
---|---|
Stores specific configuration for migrations | |
type migration_config: | |
dict |