fictive.sqlalchemy.framework package

Subpackages

fictive.sqlalchemy.framework.builtins

import these to create new resources (usually not what you want to do)

fictive.sqlalchemy.framework.shared

import these to use the framework’s shared resources (usually what you want to do)

Submodules

fictive.sqlalchemy.framework.defaults

reasonable default values for working with SQLAlchemy

Module contents

Framework compponents for sharing SQLAlchemy metadata between packages and projects

Packages may want to provide SQLAlchemy tables, models, etc. that can be readily imported and used by projects. However, a project using SQLAlchemy will most often prefer (or require) all of the tables, models, etc. to be declared in a shared sqlalchemy.schema.MetaData. Packages can provide the tables, models, etc. as “mixins” that the project can proactively integrate with the project’s MetaData instance, but this can be awkward and burdensome to the project developer. As an alternative, fictive.sqlalchemy provides some “framework” objects that are intended to be shared between packages. E.g.:

# package.py

from sqlalchemy import Table, Column, Integer, String
from fictive.sqlalchemy.framework.shared.metadata import metadata

widget_table = Table(
    'package_widget',
    # this table will be part of the shared `fictive.sqlalchemy`
    # framework metadata
    metadata,
    Column('id', Integer, primary_key=True),
    Column('value', String),
)
# project.py

from sqlalchemy import create_engine
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
from fictive.sqlalchemy.framework.shared.declarative_base import DeclarativeBase

# the shared `DeclarativeBase` uses the shared metadata, so any
# classes that use the shared `DeclarativeBase` will also be a
# part of the framework metadata
class Sprocket(DeclarativeBase):
    __tablename__ = 'project_sprocket'
    id = Column(Integer, primary_key=True)
    value = Column(String)
    widget_id = ForeignKey('package_widget.id')
>>> engine = create_engine('sqlite:///:memory:')
>>> DeclarativeBase.metadata.create_all(engine)
>>> from package import widget_table
>>> engine.execute(widget_table.insert().values(value='first widget'))
<sqlalchemy.engine.result.ResultProxy object at ...>
>>> widget = engine.execute(widget_table.select()).fetchone()
>>> sprocket = Sprocket(value='first sprocket', widget_id=widget.id)
>>> from sqlalchemy.orm import sessionmaker
>>> Session = sessionmaker(bind=engine)
>>> session = Session()
>>> session.add(sprocket)
>>> session.commit()
>>> sprocket = session.query(Sprocket).one()
>>> sprocket.widget_id == widget.id
True