sqlalchemy.ext.declarative.
declarative_base
(bind=None, metadata=None, mapper=None, cls=<class 'object'>, name='Base', constructor=<function _declarative_constructor>, class_registry=None, metaclass=<class 'sqlalchemy.ext.declarative.api.DeclarativeMeta'>)¶Construct a base class for declarative class definitions.
The new base class will be given a metaclass that produces
appropriate Table
objects and makes
the appropriate mapper()
calls based on the
information provided declaratively in the class and any subclasses
of the class.
Parameters: |
|
---|
Changed in version 1.1: if declarative_base.cls
is a
single class (rather than a tuple), the constructed base class will
inherit its docstring.
See also
sqlalchemy.ext.declarative.
as_declarative
(**kw)¶Class decorator for declarative_base()
.
Provides a syntactical shortcut to the cls
argument
sent to declarative_base()
, allowing the base class
to be converted in-place to a “declarative” base:
from sqlalchemy.ext.declarative import as_declarative
@as_declarative()
class Base(object):
@declared_attr
def __tablename__(cls):
return cls.__name__.lower()
id = Column(Integer, primary_key=True)
class MyMappedClass(Base):
# ...
All keyword arguments passed to as_declarative()
are passed
along to declarative_base()
.
See also
sqlalchemy.ext.declarative.
declared_attr
(fget, cascading=False)¶Bases: sqlalchemy.orm.base._MappedAttribute
, builtins.property
Mark a class-level method as representing the definition of a mapped property or special declarative member name.
@declared_attr turns the attribute into a scalar-like property that can be invoked from the uninstantiated class. Declarative treats attributes specifically marked with @declared_attr as returning a construct that is specific to mapping or declarative table configuration. The name of the attribute is that of what the non-dynamic version of the attribute would be.
@declared_attr is more often than not applicable to mixins, to define relationships that are to be applied to different implementors of the class:
class ProvidesUser(object):
"A mixin that adds a 'user' relationship to classes."
@declared_attr
def user(self):
return relationship("User")
It also can be applied to mapped classes, such as to provide a “polymorphic” scheme for inheritance:
class Employee(Base):
id = Column(Integer, primary_key=True)
type = Column(String(50), nullable=False)
@declared_attr
def __tablename__(cls):
return cls.__name__.lower()
@declared_attr
def __mapper_args__(cls):
if cls.__name__ == 'Employee':
return {
"polymorphic_on":cls.type,
"polymorphic_identity":"Employee"
}
else:
return {"polymorphic_identity":cls.__name__}
cascading
¶Mark a declared_attr
as cascading.
This is a special-use modifier which indicates that a column or MapperProperty-based declared attribute should be configured distinctly per mapped subclass, within a mapped-inheritance scenario.
Warning
The declared_attr.cascading
modifier has several
limitations:
declared_attr
on declarative mixin classes and __abstract__
classes; it
currently has no effect when used on a mapped class directly.__tablename__
.
On these attributes it has no effect.Below, both MyClass as well as MySubClass will have a distinct
id
Column object established:
class HasIdMixin(object):
@declared_attr.cascading
def id(cls):
if has_inherited_table(cls):
return Column(
ForeignKey('myclass.id'), primary_key=True)
else:
return Column(Integer, primary_key=True)
class MyClass(HasIdMixin, Base):
__tablename__ = 'myclass'
# ...
class MySubClass(MyClass):
""
# ...
The behavior of the above configuration is that MySubClass
will refer to both its own id
column as well as that of
MyClass
underneath the attribute named some_id
.
sqlalchemy.ext.declarative.api.
_declarative_constructor
(self, **kwargs)¶A simple constructor that allows initialization from kwargs.
Sets attributes on the constructed instance using the names and
values in kwargs
.
Only keys that are present as attributes of the instance’s class are allowed. These could be, for example, any mapped columns or relationships.
sqlalchemy.ext.declarative.
has_inherited_table
(cls)¶Given a class, return True if any of the classes it inherits from has a mapped table, otherwise return False.
This is used in declarative mixins to build attributes that behave differently for the base class vs. a subclass in an inheritance hierarchy.
sqlalchemy.ext.declarative.
synonym_for
(name, map_column=False)¶Decorator that produces an orm.synonym()
attribute in conjunction
with a Python descriptor.
The function being decorated is passed to orm.synonym()
as the
orm.synonym.descriptor
parameter:
class MyClass(Base):
__tablename__ = 'my_table'
id = Column(Integer, primary_key=True)
_job_status = Column("job_status", String(50))
@synonym_for("job_status")
@property
def job_status(self):
return "Status: %s" % self._job_status
The hybrid properties feature of SQLAlchemy is typically preferred instead of synonyms, which is a more legacy feature.
See also
Synonyms - Overview of synonyms
orm.synonym()
- the mapper-level function
Using Descriptors and Hybrids - The Hybrid Attribute extension provides an updated approach to augmenting attribute behavior more flexibly than can be achieved with synonyms.
sqlalchemy.ext.declarative.
comparable_using
(comparator_factory)¶Decorator, allow a Python @property to be used in query criteria.
This is a decorator front end to
comparable_property()
that passes
through the comparator_factory and the function being decorated:
@comparable_using(MyComparatorType)
@property
def prop(self):
return 'special sauce'
The regular comparable_property()
is also usable directly in a
declarative setting and may be convenient for read/write properties:
prop = comparable_property(MyComparatorType)
sqlalchemy.ext.declarative.
instrument_declarative
(cls, registry, metadata)¶Given a class, configure the class declaratively, using the given registry, which can be any dictionary, and MetaData object.
sqlalchemy.ext.declarative.
AbstractConcreteBase
¶Bases: sqlalchemy.ext.declarative.api.ConcreteBase
A helper class for ‘concrete’ declarative mappings.
AbstractConcreteBase
will use the polymorphic_union()
function automatically, against all tables mapped as a subclass
to this class. The function is called via the
__declare_last__()
function, which is essentially
a hook for the after_configured()
event.
AbstractConcreteBase
does produce a mapped class
for the base class, however it is not persisted to any table; it
is instead mapped directly to the “polymorphic” selectable directly
and is only used for selecting. Compare to ConcreteBase
,
which does create a persisted table for the base class.
Note
The AbstractConcreteBase
class does not intend to set up the
mapping for the base class until all the subclasses have been defined,
as it needs to create a mapping against a selectable that will include
all subclass tables. In order to achieve this, it waits for the
mapper configuration event to occur, at which point it scans
through all the configured subclasses and sets up a mapping that will
query against all subclasses at once.
While this event is normally invoked automatically, in the case of
AbstractConcreteBase
, it may be necessary to invoke it
explicitly after all subclass mappings are defined, if the first
operation is to be a query against this base class. To do so, invoke
configure_mappers()
once all the desired classes have been
configured:
from sqlalchemy.orm import configure_mappers
configure_mappers()
See also
Example:
from sqlalchemy.ext.declarative import AbstractConcreteBase
class Employee(AbstractConcreteBase, Base):
pass
class Manager(Employee):
__tablename__ = 'manager'
employee_id = Column(Integer, primary_key=True)
name = Column(String(50))
manager_data = Column(String(40))
__mapper_args__ = {
'polymorphic_identity':'manager',
'concrete':True}
configure_mappers()
The abstract base class is handled by declarative in a special way;
at class configuration time, it behaves like a declarative mixin
or an __abstract__
base class. Once classes are configured
and mappings are produced, it then gets mapped itself, but
after all of its descendants. This is a very unique system of mapping
not found in any other SQLAlchemy system.
Using this approach, we can specify columns and properties that will take place on mapped subclasses, in the way that we normally do as in Mixin and Custom Base Classes:
class Company(Base):
__tablename__ = 'company'
id = Column(Integer, primary_key=True)
class Employee(AbstractConcreteBase, Base):
employee_id = Column(Integer, primary_key=True)
@declared_attr
def company_id(cls):
return Column(ForeignKey('company.id'))
@declared_attr
def company(cls):
return relationship("Company")
class Manager(Employee):
__tablename__ = 'manager'
name = Column(String(50))
manager_data = Column(String(40))
__mapper_args__ = {
'polymorphic_identity':'manager',
'concrete':True}
configure_mappers()
When we make use of our mappings however, both Manager
and
Employee
will have an independently usable .company
attribute:
session.query(Employee).filter(Employee.company.has(id=5))
Changed in version 1.0.0: - The mechanics of AbstractConcreteBase
have been reworked to support relationships established directly
on the abstract base, without any special configurational steps.
sqlalchemy.ext.declarative.
ConcreteBase
¶A helper class for ‘concrete’ declarative mappings.
ConcreteBase
will use the polymorphic_union()
function automatically, against all tables mapped as a subclass
to this class. The function is called via the
__declare_last__()
function, which is essentially
a hook for the after_configured()
event.
ConcreteBase
produces a mapped
table for the class itself. Compare to AbstractConcreteBase
,
which does not.
Example:
from sqlalchemy.ext.declarative import ConcreteBase
class Employee(ConcreteBase, Base):
__tablename__ = 'employee'
employee_id = Column(Integer, primary_key=True)
name = Column(String(50))
__mapper_args__ = {
'polymorphic_identity':'employee',
'concrete':True}
class Manager(Employee):
__tablename__ = 'manager'
employee_id = Column(Integer, primary_key=True)
name = Column(String(50))
manager_data = Column(String(40))
__mapper_args__ = {
'polymorphic_identity':'manager',
'concrete':True}
sqlalchemy.ext.declarative.
DeferredReflection
¶A helper class for construction of mappings based on a deferred reflection step.
Normally, declarative can be used with reflection by
setting a Table
object using autoload=True
as the __table__
attribute on a declarative class.
The caveat is that the Table
must be fully
reflected, or at the very least have a primary key column,
at the point at which a normal declarative mapping is
constructed, meaning the Engine
must be available
at class declaration time.
The DeferredReflection
mixin moves the construction
of mappers to be at a later point, after a specific
method is called which first reflects all Table
objects created so far. Classes can define it as such:
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.declarative import DeferredReflection
Base = declarative_base()
class MyClass(DeferredReflection, Base):
__tablename__ = 'mytable'
Above, MyClass
is not yet mapped. After a series of
classes have been defined in the above fashion, all tables
can be reflected and mappings created using
prepare()
:
engine = create_engine("someengine://...")
DeferredReflection.prepare(engine)
The DeferredReflection
mixin can be applied to individual
classes, used as the base for the declarative base itself,
or used in a custom abstract class. Using an abstract base
allows that only a subset of classes to be prepared for a
particular prepare step, which is necessary for applications
that use more than one engine. For example, if an application
has two engines, you might use two bases, and prepare each
separately, e.g.:
class ReflectedOne(DeferredReflection, Base):
__abstract__ = True
class ReflectedTwo(DeferredReflection, Base):
__abstract__ = True
class MyClass(ReflectedOne):
__tablename__ = 'mytable'
class MyOtherClass(ReflectedOne):
__tablename__ = 'myothertable'
class YetAnotherClass(ReflectedTwo):
__tablename__ = 'yetanothertable'
# ... etc.
Above, the class hierarchies for ReflectedOne
and
ReflectedTwo
can be configured separately:
ReflectedOne.prepare(engine_one)
ReflectedTwo.prepare(engine_two)
prepare
(engine)¶Reflect all Table
objects for all current
DeferredReflection
subclasses
__declare_last__()
¶The __declare_last__()
hook allows definition of
a class level function that is automatically called by the
MapperEvents.after_configured()
event, which occurs after mappings are
assumed to be completed and the ‘configure’ step has finished:
class MyClass(Base):
@classmethod
def __declare_last__(cls):
""
# do something with mappings
__declare_first__()
¶Like __declare_last__()
, but is called at the beginning of mapper
configuration via the MapperEvents.before_configured()
event:
class MyClass(Base):
@classmethod
def __declare_first__(cls):
""
# do something before mappings are configured
New in version 0.9.3.
__abstract__
¶__abstract__
causes declarative to skip the production
of a table or mapper for the class entirely. A class can be added within a
hierarchy in the same way as mixin (see Mixin and Custom Base Classes), allowing
subclasses to extend just from the special class:
class SomeAbstractBase(Base):
__abstract__ = True
def some_helpful_method(self):
""
@declared_attr
def __mapper_args__(cls):
return {"helpful mapper arguments":True}
class MyMappedClass(SomeAbstractBase):
""
One possible use of __abstract__
is to use a distinct
MetaData
for different bases:
Base = declarative_base()
class DefaultBase(Base):
__abstract__ = True
metadata = MetaData()
class OtherBase(Base):
__abstract__ = True
metadata = MetaData()
Above, classes which inherit from DefaultBase
will use one
MetaData
as the registry of tables, and those which inherit from
OtherBase
will use a different one. The tables themselves can then be
created perhaps within distinct databases:
DefaultBase.metadata.create_all(some_engine)
OtherBase.metadata_create_all(some_other_engine)
__table_cls__
¶Allows the callable / class used to generate a Table
to be customized.
This is a very open-ended hook that can allow special customizations
to a Table
that one generates here:
class MyMixin(object):
@classmethod
def __table_cls__(cls, name, metadata, *arg, **kw):
return Table(
"my_" + name,
metadata, *arg, **kw
)
The above mixin would cause all Table
objects generated to include
the prefix "my_"
, followed by the name normally specified using the
__tablename__
attribute.
__table_cls__
also supports the case of returning None
, which
causes the class to be considered as single-table inheritance vs. its subclass.
This may be useful in some customization schemes to determine that single-table
inheritance should take place based on the arguments for the table itself,
such as, define as single-inheritance if there is no primary key present:
class AutoTable(object):
@declared_attr
def __tablename__(cls):
return cls.__name__
@classmethod
def __table_cls__(cls, *arg, **kw):
for obj in arg[1:]:
if (isinstance(obj, Column) and obj.primary_key) or \
isinstance(obj, PrimaryKeyConstraint):
return Table(*arg, **kw)
return None
class Person(AutoTable, Base):
id = Column(Integer, primary_key=True)
class Employee(Person):
employee_name = Column(String)
The above Employee
class would be mapped as single-table inheritance
against Person
; the employee_name
column would be added as a member
of the Person
table.
New in version 1.0.0.