# mapping attributes using declarative with declarative table
# i.e. __tablename__
- from sqlalchemy import Column, Integer, String, Text, ForeignKey
- from sqlalchemy.orm import column_property, relationship, deferred
- from sqlalchemy.orm import declarative_base
+ from sqlalchemy import Column, ForeignKey, Integer, String, Text
+ from sqlalchemy.orm import (
+ column_property,
+ declarative_base,
+ deferred,
+ relationship,
+ )
Base = declarative_base()
+
class User(Base):
- __tablename__ = 'user'
+ __tablename__ = "user"
id = Column(Integer, primary_key=True)
name = Column(String)
addresses = relationship("Address", back_populates="user")
+
class Address(Base):
- __tablename__ = 'address'
+ __tablename__ = "address"
id = Column(Integer, primary_key=True)
user_id = Column(ForeignKey("user.id"))
# mapping attributes using declarative with imperative table
# i.e. __table__
- from sqlalchemy import Table
- from sqlalchemy import Column, Integer, String, Text, ForeignKey
- from sqlalchemy.orm import column_property, relationship, deferred
- from sqlalchemy.orm import declarative_base
+ from sqlalchemy import Column, ForeignKey, Integer, String, Table, Text
+ from sqlalchemy.orm import (
+ column_property,
+ declarative_base,
+ deferred,
+ relationship,
+ )
Base = declarative_base()
+
class User(Base):
__table__ = Table(
"user",
Column("id", Integer, primary_key=True),
Column("name", String),
Column("firstname", String(50)),
- Column("lastname", String(50))
+ Column("lastname", String(50)),
)
- fullname = column_property(__table__.c.firstname + " " + __table__.c.lastname)
+ fullname = column_property(
+ __table__.c.firstname + " " + __table__.c.lastname
+ )
addresses = relationship("Address", back_populates="user")
+
class Address(Base):
__table__ = Table(
"address",
Column("id", Integer, primary_key=True),
Column("user_id", ForeignKey("user.id")),
Column("email_address", String),
- Column("address_statistics", Text)
+ Column("address_statistics", Text),
)
address_statistics = deferred(__table__.c.address_statistics)
from datetime import datetime
+
class Widget(Base):
- __tablename__ = 'widgets'
+ __tablename__ = "widgets"
id = Column(Integer, primary_key=True)
timestamp = Column(DateTime, nullable=False)
__mapper_args__ = {
- 'version_id_col': timestamp,
- 'version_id_generator': lambda v:datetime.now()
+ "version_id_col": timestamp,
+ "version_id_generator": lambda v: datetime.now(),
}
**Single Table Inheritance**
:paramref:`_orm.Mapper.polymorphic_identity` parameters::
class Person(Base):
- __tablename__ = 'person'
+ __tablename__ = "person"
person_id = Column(Integer, primary_key=True)
type = Column(String, nullable=False)
__mapper_args__ = dict(
polymorphic_on=type,
- polymorphic_identity="person"
+ polymorphic_identity="person",
)
+
class Employee(Person):
__mapper_args__ = dict(
- polymorphic_identity="employee"
+ polymorphic_identity="employee",
)
The ``__mapper_args__`` dictionary may be generated from a class-bound
reg = registry()
+
class BaseOne:
metadata = MetaData()
+
class BaseTwo:
metadata = MetaData()
+
@reg.mapped
class ClassOne:
- __tablename__ = 't1' # will use reg.metadata
+ __tablename__ = "t1" # will use reg.metadata
id = Column(Integer, primary_key=True)
+
@reg.mapped
class ClassTwo(BaseOne):
- __tablename__ = 't1' # will use BaseOne.metadata
+ __tablename__ = "t1" # will use BaseOne.metadata
id = Column(Integer, primary_key=True)
+
@reg.mapped
class ClassThree(BaseTwo):
- __tablename__ = 't1' # will use BaseTwo.metadata
+ __tablename__ = "t1" # will use BaseTwo.metadata
id = Column(Integer, primary_key=True)
-
.. versionchanged:: 1.4.3 The :meth:`_orm.registry.mapped` decorator will
honor an attribute named ``.metadata`` on the class as an alternate
:class:`_schema.MetaData` collection to be used in place of the
__abstract__ = True
def some_helpful_method(self):
- ""
+ """"""
@declared_attr
def __mapper_args__(cls):
- return {"helpful mapper arguments":True}
+ return {"helpful mapper arguments": True}
+
class MyMappedClass(SomeAbstractBase):
- ""
+ pass
One possible use of ``__abstract__`` is to use a distinct
:class:`_schema.MetaData` for different bases::
Base = declarative_base()
+
class DefaultBase(Base):
__abstract__ = True
metadata = MetaData()
+
class OtherBase(Base):
__abstract__ = True
metadata = MetaData()
DefaultBase.metadata.create_all(some_engine)
OtherBase.metadata.create_all(some_other_engine)
-
``__table_cls__``
~~~~~~~~~~~~~~~~~
class MyMixin:
@classmethod
def __table_cls__(cls, name, metadata_obj, *arg, **kw):
- return Table(
- "my_" + name,
- metadata_obj, *arg, **kw
- )
+ return Table(f"my_{name}", metadata_obj, *arg, **kw)
The above mixin would cause all :class:`_schema.Table` objects generated to include
the prefix ``"my_"``, followed by the name normally specified using the
@classmethod
def __table_cls__(cls, *arg, **kw):
for obj in arg[1:]:
- if (isinstance(obj, Column) and obj.primary_key) or \
- isinstance(obj, PrimaryKeyConstraint):
+ 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)