Declarative API

API Reference

  • sqlalchemy.ext.declarative.declarativebase(_bind=None, metadata=None, mapper=None, cls=, name='Base', constructor=, class_registry=None, metaclass=)
  • Construct a base class for declarative class definitions.

The new base class will be given a metaclass that producesappropriate Table objects and makesthe appropriate mapper() calls based on theinformation provided declaratively in the class and any subclassesof the class.

  • Parameters
    • bind – An optionalConnectable, will be assignedthe bind attribute on the MetaDatainstance.

    • metadata – An optional MetaData instance. AllTable objects implicitly declared bysubclasses of the base will share this MetaData. A MetaData instancewill be created if none is provided. TheMetaData instance will be available via themetadata attribute of the generated declarative base class.

    • mapper – An optional callable, defaults to mapper(). Willbe used to map subclasses to their Tables.

    • cls – Defaults to object. A type to use as the base for the generateddeclarative base class. May be a class or tuple of classes.

    • name – Defaults to Base. The display name for the generatedclass. Customizing this is not required, but can improve clarity intracebacks and debugging.

    • constructor – Defaults todeclarativeconstructor(), aninit implementation that assigns **kwargs for declaredfields and relationships to an instance. If None is supplied,no init will be provided and construction will fall back tocls.__init by way of the normal Python semantics.

    • class_registry – optional dictionary that will serve as theregistry of class names-> mapped classes when string namesare used to identify classes inside of relationship()and others. Allows two or more declarative base classesto share the same registry of class names for simplifiedinter-base relationships.

    • metaclass – Defaults to DeclarativeMeta. A metaclass or metaclasscompatible callable to use as the meta type of the generateddeclarative base class.

Changed in version 1.1: if declarative_base.cls is asingle class (rather than a tuple), the constructed base class willinherit its docstring.

See also

as_declarative()

Provides a syntactical shortcut to the cls argumentsent to declarative_base(), allowing the base classto be converted in-place to a “declarative” base:

  1. from sqlalchemy.ext.declarative import as_declarative
  2.  
  3. @as_declarative()
  4. class Base(object):
  5. @declared_attr
  6. def __tablename__(cls):
  7. return cls.__name__.lower()
  8. id = Column(Integer, primary_key=True)
  9.  
  10. class MyMappedClass(Base):
  11. # ...

All keyword arguments passed to as_declarative() are passedalong to declarative_base().

See also

declarative_base()

  • class sqlalchemy.ext.declarative.declaredattr(_fget, cascading=False)
  • Bases: sqlalchemy.orm.base._MappedAttribute, builtins.property

Mark a class-level method as representing the definition ofa mapped property or special declarative member name.

@declared_attr turns the attribute into a scalar-likeproperty that can be invoked from the uninstantiated class.Declarative treats attributes specifically marked with@declared_attr as returning a construct that is specificto mapping or declarative table configuration. The nameof the attribute is that of what the non-dynamic versionof the attribute would be.

@declared_attr is more often than not applicable to mixins,to define relationships that are to be applied to differentimplementors of the class:

  1. class ProvidesUser(object):
  2. "A mixin that adds a 'user' relationship to classes."
  3.  
  4. @declared_attr
  5. def user(self):
  6. return relationship("User")

It also can be applied to mapped classes, such as to providea “polymorphic” scheme for inheritance:

  1. class Employee(Base):
  2. id = Column(Integer, primary_key=True)
  3. type = Column(String(50), nullable=False)
  4.  
  5. @declared_attr
  6. def __tablename__(cls):
  7. return cls.__name__.lower()
  8.  
  9. @declared_attr
  10. def __mapper_args__(cls):
  11. if cls.__name__ == 'Employee':
  12. return {
  13. "polymorphic_on":cls.type,
  14. "polymorphic_identity":"Employee"
  15. }
  16. else:
  17. return {"polymorphic_identity":cls.__name__}

This is a special-use modifier which indicates that a columnor MapperProperty-based declared attribute should be configureddistinctly per mapped subclass, within a mapped-inheritance scenario.

Warning

The declared_attr.cascading modifier has severallimitations:

  1. -

The flag only applies to the use of declared_attron declarative mixin classes and abstract classes; itcurrently has no effect when used on a mapped class directly.

  1. -

The flag only applies to normally-named attributes, e.g.not any special underscore attributes such as tablename.On these attributes it has no effect.

  1. -

The flag currently does not allow further overrides downthe class hierarchy; if a subclass tries to override theattribute, a warning is emitted and the overridden attributeis skipped. This is a limitation that it is hoped will beresolved at some point.

Below, both MyClass as well as MySubClass will have a distinctid Column object established:

  1. class HasIdMixin(object):
  2. @declared_attr.cascading
  3. def id(cls):
  4. if has_inherited_table(cls):
  5. return Column(
  6. ForeignKey('myclass.id'), primary_key=True)
  7. else:
  8. return Column(Integer, primary_key=True)
  9.  
  10. class MyClass(HasIdMixin, Base):
  11. __tablename__ = 'myclass'
  12. # ...
  13.  
  14. class MySubClass(MyClass):
  15. ""
  16. # ...

The behavior of the above configuration is that MySubClasswill refer to both its own id column as well as that ofMyClass underneath the attribute named some_id.

See also

Inheritance Configuration

Mixing in Columns in Inheritance Scenarios

  • 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 andvalues in kwargs.

Only keys that are present asattributes of the instance’s class are allowed. These could be,for example, any mapped columns or relationships.

  • sqlalchemy.ext.declarative.hasinherited_table(_cls)
  • Given a class, return True if any of the classes it inherits from has amapped table, otherwise return False.

This is used in declarative mixins to build attributes that behavedifferently for the base class vs. a subclass in an inheritancehierarchy.

See also

Controlling table inheritance with mixins

  • sqlalchemy.ext.declarative.synonymfor(_name, map_column=False)
  • Decorator that produces an orm.synonym() attribute in conjunctionwith a Python descriptor.

The function being decorated is passed to orm.synonym() as theorm.synonym.descriptor parameter:

  1. class MyClass(Base):
  2. __tablename__ = 'my_table'
  3.  
  4. id = Column(Integer, primary_key=True)
  5. _job_status = Column("job_status", String(50))
  6.  
  7. @synonym_for("job_status")
  8. @property
  9. def job_status(self):
  10. return "Status: %s" % self._job_status

The hybrid properties feature of SQLAlchemyis typically preferred instead of synonyms, which is a more legacyfeature.

See also

Synonyms - Overview of synonyms

orm.synonym() - the mapper-level function

Using Descriptors and Hybrids - The Hybrid Attribute extension provides anupdated approach to augmenting attribute behavior more flexibly thancan be achieved with synonyms.

  • sqlalchemy.ext.declarative.comparableusing(_comparator_factory)
  • Decorator, allow a Python @property to be used in query criteria.

This is a decorator front end tocomparable_property() that passesthrough the comparator_factory and the function being decorated:

  1. @comparable_using(MyComparatorType)@propertydef prop(self): return 'special sauce'

The regular comparable_property() is also usable directly in adeclarative setting and may be convenient for read/write properties:

  1. prop = comparable_property(MyComparatorType)
  • sqlalchemy.ext.declarative.instrumentdeclarative(_cls, registry, metadata)
  • Given a class, configure the class declaratively,using the given registry, which can be any dictionary, andMetaData object.

  • class 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 subclassto this class. The function is called via thedeclare_last() function, which is essentiallya hook for the after_configured() event.

AbstractConcreteBase does produce a mapped classfor the base class, however it is not persisted to any table; itis instead mapped directly to the “polymorphic” selectable directlyand 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 themapping for the base class until all the subclasses have been defined,as it needs to create a mapping against a selectable that will includeall subclass tables. In order to achieve this, it waits for themapper configuration event to occur, at which point it scansthrough all the configured subclasses and sets up a mapping that willquery against all subclasses at once.

While this event is normally invoked automatically, in the case ofAbstractConcreteBase, it may be necessary to invoke itexplicitly after all subclass mappings are defined, if the firstoperation is to be a query against this base class. To do so, invokeconfigure_mappers() once all the desired classes have beenconfigured:

  1. from sqlalchemy.orm import configure_mappers
  2.  
  3. configure_mappers()

See also

orm.configure_mappers()

Example:

  1. from sqlalchemy.ext.declarative import AbstractConcreteBase
  2.  
  3. class Employee(AbstractConcreteBase, Base):
  4. pass
  5.  
  6. class Manager(Employee):
  7. __tablename__ = 'manager'
  8. employee_id = Column(Integer, primary_key=True)
  9. name = Column(String(50))
  10. manager_data = Column(String(40))
  11.  
  12. __mapper_args__ = {
  13. 'polymorphic_identity':'manager',
  14. 'concrete':True}
  15.  
  16. configure_mappers()

The abstract base class is handled by declarative in a special way;at class configuration time, it behaves like a declarative mixinor an abstract base class. Once classes are configuredand mappings are produced, it then gets mapped itself, butafter all of its descendants. This is a very unique system of mappingnot found in any other SQLAlchemy system.

Using this approach, we can specify columns and propertiesthat will take place on mapped subclasses, in the way thatwe normally do as in Mixin and Custom Base Classes:

  1. class Company(Base):
  2. __tablename__ = 'company'
  3. id = Column(Integer, primary_key=True)
  4.  
  5. class Employee(AbstractConcreteBase, Base):
  6. employee_id = Column(Integer, primary_key=True)
  7.  
  8. @declared_attr
  9. def company_id(cls):
  10. return Column(ForeignKey('company.id'))
  11.  
  12. @declared_attr
  13. def company(cls):
  14. return relationship("Company")
  15.  
  16. class Manager(Employee):
  17. __tablename__ = 'manager'
  18.  
  19. name = Column(String(50))
  20. manager_data = Column(String(40))
  21.  
  22. __mapper_args__ = {
  23. 'polymorphic_identity':'manager',
  24. 'concrete':True}
  25.  
  26. configure_mappers()

When we make use of our mappings however, both Manager andEmployee will have an independently usable .company attribute:

  1. session.query(Employee).filter(Employee.company.has(id=5))

Changed in version 1.0.0: - The mechanics of AbstractConcreteBasehave been reworked to support relationships established directlyon the abstract base, without any special configurational steps.

See also

ConcreteBase

Concrete Table Inheritance

inheritance_concrete_helpers

  • class 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 subclassto this class. The function is called via thedeclare_last() function, which is essentiallya hook for the after_configured() event.

ConcreteBase produces a mappedtable for the class itself. Compare to AbstractConcreteBase,which does not.

Example:

  1. from sqlalchemy.ext.declarative import ConcreteBase
  2.  
  3. class Employee(ConcreteBase, Base):
  4. __tablename__ = 'employee'
  5. employee_id = Column(Integer, primary_key=True)
  6. name = Column(String(50))
  7. __mapper_args__ = {
  8. 'polymorphic_identity':'employee',
  9. 'concrete':True}
  10.  
  11. class Manager(Employee):
  12. __tablename__ = 'manager'
  13. employee_id = Column(Integer, primary_key=True)
  14. name = Column(String(50))
  15. manager_data = Column(String(40))
  16. __mapper_args__ = {
  17. 'polymorphic_identity':'manager',
  18. 'concrete':True}

See also

AbstractConcreteBase

Concrete Table Inheritance

inheritance_concrete_helpers

  • class sqlalchemy.ext.declarative.DeferredReflection
  • A helper class for construction of mappings based ona deferred reflection step.

Normally, declarative can be used with reflection bysetting a Table object using autoload=Trueas the table attribute on a declarative class.The caveat is that the Table must be fullyreflected, or at the very least have a primary key column,at the point at which a normal declarative mapping isconstructed, meaning the Engine must be availableat class declaration time.

The DeferredReflection mixin moves the constructionof mappers to be at a later point, after a specificmethod is called which first reflects all Tableobjects created so far. Classes can define it as such:

  1. from sqlalchemy.ext.declarative import declarative_base
  2. from sqlalchemy.ext.declarative import DeferredReflection
  3. Base = declarative_base()
  4.  
  5. class MyClass(DeferredReflection, Base):
  6. __tablename__ = 'mytable'

Above, MyClass is not yet mapped. After a series ofclasses have been defined in the above fashion, all tablescan be reflected and mappings created usingprepare():

  1. engine = create_engine("someengine://...")
  2. DeferredReflection.prepare(engine)

The DeferredReflection mixin can be applied to individualclasses, used as the base for the declarative base itself,or used in a custom abstract class. Using an abstract baseallows that only a subset of classes to be prepared for aparticular prepare step, which is necessary for applicationsthat use more than one engine. For example, if an applicationhas two engines, you might use two bases, and prepare eachseparately, e.g.:

  1. class ReflectedOne(DeferredReflection, Base):
  2. __abstract__ = True
  3.  
  4. class ReflectedTwo(DeferredReflection, Base):
  5. __abstract__ = True
  6.  
  7. class MyClass(ReflectedOne):
  8. __tablename__ = 'mytable'
  9.  
  10. class MyOtherClass(ReflectedOne):
  11. __tablename__ = 'myothertable'
  12.  
  13. class YetAnotherClass(ReflectedTwo):
  14. __tablename__ = 'yetanothertable'
  15.  
  16. # ... etc.

Above, the class hierarchies for ReflectedOne andReflectedTwo can be configured separately:

  1. ReflectedOne.prepare(engine_one)
  2. ReflectedTwo.prepare(engine_two)

Special Directives

declare_last()

The declare_last() hook allows definition ofa class level function that is automatically called by theMapperEvents.after_configured() event, which occurs after mappings areassumed to be completed and the ‘configure’ step has finished:

  1. class MyClass(Base):
  2. @classmethod
  3. def __declare_last__(cls):
  4. ""
  5. # do something with mappings

declare_first()

Like declare_last(), but is called at the beginning of mapperconfiguration via the MapperEvents.before_configured() event:

  1. class MyClass(Base):
  2. @classmethod
  3. def __declare_first__(cls):
  4. ""
  5. # do something before mappings are configured

New in version 0.9.3.

abstract

abstract causes declarative to skip the productionof a table or mapper for the class entirely. A class can be added within ahierarchy in the same way as mixin (see Mixin and Custom Base Classes), allowingsubclasses to extend just from the special class:

  1. class SomeAbstractBase(Base):
  2. __abstract__ = True
  3.  
  4. def some_helpful_method(self):
  5. ""
  6.  
  7. @declared_attr
  8. def __mapper_args__(cls):
  9. return {"helpful mapper arguments":True}
  10.  
  11. class MyMappedClass(SomeAbstractBase):
  12. ""

One possible use of abstract is to use a distinctMetaData for different bases:

  1. Base = declarative_base()
  2.  
  3. class DefaultBase(Base):
  4. __abstract__ = True
  5. metadata = MetaData()
  6.  
  7. class OtherBase(Base):
  8. __abstract__ = True
  9. metadata = MetaData()

Above, classes which inherit from DefaultBase will use oneMetaData as the registry of tables, and those which inherit fromOtherBase will use a different one. The tables themselves can then becreated perhaps within distinct databases:

  1. DefaultBase.metadata.create_all(some_engine)
  2. 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 customizationsto a Table that one generates here:

  1. class MyMixin(object):
  2. @classmethod
  3. def __table_cls__(cls, name, metadata, *arg, **kw):
  4. return Table(
  5. "my_" + name,
  6. metadata, *arg, **kw
  7. )

The above mixin would cause all Table objects generated to includethe prefix "my", followed by the name normally specified using the_tablename attribute.

table_cls also supports the case of returning None, whichcauses the class to be considered as single-table inheritance vs. its subclass.This may be useful in some customization schemes to determine that single-tableinheritance should take place based on the arguments for the table itself,such as, define as single-inheritance if there is no primary key present:

  1. class AutoTable(object):
  2. @declared_attr
  3. def __tablename__(cls):
  4. return cls.__name__
  5.  
  6. @classmethod
  7. def __table_cls__(cls, *arg, **kw):
  8. for obj in arg[1:]:
  9. if (isinstance(obj, Column) and obj.primary_key) or \
  10. isinstance(obj, PrimaryKeyConstraint):
  11. return Table(*arg, **kw)
  12.  
  13. return None
  14.  
  15. class Person(AutoTable, Base):
  16. id = Column(Integer, primary_key=True)
  17.  
  18. class Employee(Person):
  19. employee_name = Column(String)

The above Employee class would be mapped as single-table inheritanceagainst Person; the employee_name column would be added as a memberof the Person table.

New in version 1.0.0.