SQLAlchemy 2.0 Documentation
SQLAlchemy ORM
- ORM Quick Start
- ORM Mapped Class Configuration
- Relationship Configuration
- ORM Querying Guide
- Using the Session
- Events and Internals
- ORM Extensions
- ORM Examples
Project Versions
Declarative Extensions¶
Extensions specific to the Declarative mapping API.
Changed in version 1.4: The vast majority of the Declarative extension is now integrated into the SQLAlchemy ORM and is importable from the sqlalchemy.orm namespace. See the documentation at Declarative Mapping for new documentation. For an overview of the change, see Declarative is now integrated into the ORM with new features.
| Object Name | Description |
|---|---|
A helper class for ‘concrete’ declarative mappings. | |
A helper class for construction of mappings based on a deferred reflection step. |
- class sqlalchemy.ext.declarative.AbstractConcreteBase¶
inherits from
sqlalchemy.ext.declarative.extensions.ConcreteBaseA helper class for ‘concrete’ declarative mappings.
AbstractConcreteBasewill use thepolymorphic_union()function automatically, against all tables mapped as a subclass to this class. The function is called via the__declare_first__()function, which is essentially a hook for thebefore_configured()event.AbstractConcreteBaseappliesMapperfor its immediately inheriting class, as would occur for any other declarative mapped class. However, theMapperis not mapped to any particularTableobject. Instead, it’s mapped directly to the “polymorphic” selectable produced bypolymorphic_union(), and performs no persistence operations on its own. Compare toConcreteBase, which maps its immediately inheriting class to an actualTablethat stores rows directly.Note
The
AbstractConcreteBasedelays the mapper creation of 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, once all the desired classes have been configured, theregistry.configure()method on theregistryin use can be invoked, which is available in relation to a particular declarative base class:Base.registry.configure()
Example:
from sqlalchemy.orm import DeclarativeBase from sqlalchemy.ext.declarative import AbstractConcreteBase class Base(DeclarativeBase): pass 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, } Base.registry.configure()
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 API feature.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:
from sqlalchemy.ext.declarative import AbstractConcreteBase class Company(Base): __tablename__ = "company" id = Column(Integer, primary_key=True) class Employee(AbstractConcreteBase, Base): strict_attrs = True 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, } Base.registry.configure()
When we make use of our mappings however, both
ManagerandEmployeewill have an independently usable.companyattribute:session.execute(select(Employee).filter(Employee.company.has(id=5)))
- Parameters:
strict_attrs¶ –
when specified on the base class, “strict” attribute mode is enabled which attempts to limit ORM mapped attributes on the base class to only those that are immediately present, while still preserving “polymorphic” loading behavior.
Added in version 2.0.
- class sqlalchemy.ext.declarative.ConcreteBase¶
A helper class for ‘concrete’ declarative mappings.
ConcreteBasewill use thepolymorphic_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 theafter_configured()event.ConcreteBaseproduces a mapped table for the class itself. Compare toAbstractConcreteBase, 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, }
The name of the discriminator column used by
polymorphic_union()defaults to the nametype. To suit the use case of a mapping where an actual column in a mapped table is already namedtype, the discriminator name can be configured by setting the_concrete_discriminator_nameattribute:class Employee(ConcreteBase, Base): _concrete_discriminator_name = "_concrete_discriminator"
Added in version 1.3.19: Added the
_concrete_discriminator_nameattribute toConcreteBaseso that the virtual discriminator column name can be customized.Changed in version 1.4.2: The
_concrete_discriminator_nameattribute need only be placed on the basemost class to take correct effect for all subclasses. An explicit error message is now raised if the mapped column names conflict with the discriminator name, whereas in the 1.3.x series there would be some warnings and then a non-useful query would be generated.
- class 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
Tableobject using autoload_with=engine as the__table__attribute on a declarative class. The caveat is that theTablemust 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 theEnginemust be available at class declaration time.The
DeferredReflectionmixin moves the construction of mappers to be at a later point, after a specific method is called which first reflects allTableobjects 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,
MyClassis not yet mapped. After a series of classes have been defined in the above fashion, all tables can be reflected and mappings created usingprepare():engine = create_engine("someengine://...") DeferredReflection.prepare(engine)
The
DeferredReflectionmixin 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
ReflectedOneandReflectedTwocan be configured separately:ReflectedOne.prepare(engine_one) ReflectedTwo.prepare(engine_two)
See also
Using DeferredReflection - in the Table Configuration with Declarative section.
Member Name Description prepare()
Reflect all
Tableobjects for all currentDeferredReflectionsubclasses- classmethod
sqlalchemy.ext.declarative.DeferredReflection.prepare(bind: Engine | Connection, **reflect_kw: Any) → None¶ Reflect all
Tableobjects for all currentDeferredReflectionsubclasses- Parameters:
bind¶ –
EngineorConnectioninstance..versionchanged:: 2.0.16 a
Connectionis also accepted.**reflect_kw¶ –
additional keyword arguments passed to
MetaData.reflect(), such asMetaData.reflect.views.Added in version 2.0.16.
- classmethod
flambé! the dragon and The Alchemist image designs created and generously donated by Rotem Yaari.
Created using Sphinx 8.2.3. Documentation last generated: Tue 21 Oct 2025 06:01:18 PM EDT