fictive.sqlalchemy package¶
Subpackages¶
Framework compponents for sharing SQLAlchemy metadata between packages and projects |
Submodules¶
Custom SQLAlchemy column types |
Module contents¶
Fictive Kin library for using SQLAlchemy
-
class
fictive.sqlalchemy.FindOrCreateDescriptor(session_factory)[source]¶ Bases:
objectDescriptor for attaching a
find_or_createmethod to amodelclassfrom fictive.sqlalchemy import FindOrCreateDescriptor class Model(DeclarativeBase): __tablename__ = 'model' id = Column(Integer, primary_key=True) value = Column(String) find_or_create = FindOrCreateDescriptor(session_factory) DeclarativeBase.metadata.create_all(engine)
>>> created = Model.find_or_create(value='created') >>> session.add(created) >>> session.commit() >>> (created.id, created.value) (1, 'created') >>> retrieved = Model.find_or_create(value='created') >>> (retrieved.id, retrieved.value) (1, 'created') >>> # each call to find_or_create falls the session_factory so >>> # the instances may be in different sessions unless the >>> # factory returns the same session over multiple calls >>> # (e.g., `sqlalchemy.orm.scoping.scoped_session`) >>> retrieved is created False
-
class
fictive.sqlalchemy.ModelDescriptor(model: str, base: sqlalchemy.ext.declarative.api.DeclarativeMeta)[source]¶ Bases:
objectLazy reference to a
declarative_basesubclassIn large applications, “models” are often declared in separate files from each other and from “controllers” or “views” that utilize the models. This can easily lead to “circular import” issues in Python that can require substantial refactoring or subtle non-idiomatc hacks of Python’s import behavior.
SQLAlchemy provides some features that can alleviate this concern, most notably the Declarative extension that, among other features, allows strings to be used in place of class references. E.g.:
from sqlalchemy import Column, Integer, ForeignKey from sqlalchemy.orm import relationship from application.models import Base class ChildModel(Base): __tablename__ = 'child' id = Column(Integer, primary_key=True) parent_id = Column(ForeignKey('parent.id')) #: We don't need to `from parents import ParentModel` #: here; the string reference will be resolved at run time parent = relationship('ParentModel')
This descriptor uses the Declarative extension to wrap a string reference to a
declarative_basesubclass (i.e., a model class) in a generalized way. When the owning class calls the__get__method, the descriptor will automatically dereference the string reference and return the indicateddeclarative_basesubclass. E.g.:class MyController(object): #: We don't need to `from models import ExampleModel` #: here; the string reference will be resolved at run time model_class = ModelDescriptor('ExampleModel', Base) def describe_model(self): return self.model_class.__tablename__
>>> MyController().describe_model() 'example_model_table'
-
__init__(model: str, base: sqlalchemy.ext.declarative.api.DeclarativeMeta)[source]¶ - Parameters
model (str) – the “string name” of model class. The model class MUST be a subclass of
basebase (
sqlalchemy.ext.declarative.api.DeclarativeMeta) – a base class created bysqlalchemy.ext.declarative.declarative_base
-
-
fictive.sqlalchemy.find_or_create(session: sqlalchemy.orm.session.Session, model_class: sqlalchemy.ext.declarative.api.DeclarativeMeta, **kwargs)[source]¶ retrieves an instance from the database or creates one if it doesn’t exist
E.g.:
from sqlalchemy import Column, Integer, String from fictive.sqlalchemy import find_or_create class Model(DeclarativeBase): __tablename__ = 'model' id = Column(Integer, primary_key=True) value = Column(String) DeclarativeBase.metadata.create_all(engine)
>>> first = Model(value='first') >>> session.add(first) >>> session.commit() >>> found = find_or_create(session, Model, value='first') >>> (found.id, found.value) (1, 'first') >>> found is first True >>> created = find_or_create(session, Model, value='second') >>> (created.id, created.value) (None, 'second') >>> created in session False
- Parameters
session (
sqlalchemy.orm.session.Session) – an active SQLAlchemy sessionmodel_class (
sqlalchemy.ext.declarative.api.DeclarativeMeta) – the model class to find or create**kwargs –
these keyword arguments will be passed to
sqlalchemy.orm.query.Query.filter_by__require_unique (
bool) – require the filter criteria produce a unique result. IfFalse(the default), will return the first matching record if any exist. IfTrueand more than one matching record exists, raisessqlalchemy.orm.exc.MultipleResultsFound__suppress_errors (
bool) – suppress any SQLAlchemy ORM errors. The default isFalse. If this is set toTrue, any query errors (other thansqlalchemy.orm.exc.MultipleResultsFound) will be handled as if no matching record had been found