summaryrefslogtreecommitdiff
path: root/doc/build/orm/mapped_sql_expr.rst
diff options
context:
space:
mode:
Diffstat (limited to 'doc/build/orm/mapped_sql_expr.rst')
-rw-r--r--doc/build/orm/mapped_sql_expr.rst98
1 files changed, 56 insertions, 42 deletions
diff --git a/doc/build/orm/mapped_sql_expr.rst b/doc/build/orm/mapped_sql_expr.rst
index 818a6a952..bab903cd9 100644
--- a/doc/build/orm/mapped_sql_expr.rst
+++ b/doc/build/orm/mapped_sql_expr.rst
@@ -23,9 +23,9 @@ will provide for us the ``fullname``, which is the string concatenation of the t
class User(Base):
__tablename__ = 'user'
- id = Column(Integer, primary_key=True)
- firstname = Column(String(50))
- lastname = Column(String(50))
+ id = mapped_column(Integer, primary_key=True)
+ firstname = mapped_column(String(50))
+ lastname = mapped_column(String(50))
@hybrid_property
def fullname(self):
@@ -54,9 +54,9 @@ needs to be present inside the hybrid, using the ``if`` statement in Python and
class User(Base):
__tablename__ = 'user'
- id = Column(Integer, primary_key=True)
- firstname = Column(String(50))
- lastname = Column(String(50))
+ id = mapped_column(Integer, primary_key=True)
+ firstname = mapped_column(String(50))
+ lastname = mapped_column(String(50))
@hybrid_property
def fullname(self):
@@ -98,9 +98,9 @@ follows::
class User(Base):
__tablename__ = 'user'
- id = Column(Integer, primary_key=True)
- firstname = Column(String(50))
- lastname = Column(String(50))
+ id = mapped_column(Integer, primary_key=True)
+ firstname = mapped_column(String(50))
+ lastname = mapped_column(String(50))
fullname = column_property(firstname + " " + lastname)
Correlated subqueries may be used as well. Below we use the
@@ -112,18 +112,19 @@ of ``Address`` objects available for a particular ``User``::
from sqlalchemy import select, func
from sqlalchemy import Column, Integer, String, ForeignKey
- from sqlalchemy.ext.declarative import declarative_base
+ from sqlalchemy.orm import DeclarativeBase
- Base = declarative_base()
+ class Base(DeclarativeBase):
+ pass
class Address(Base):
__tablename__ = 'address'
- id = Column(Integer, primary_key=True)
- user_id = Column(Integer, ForeignKey('user.id'))
+ id = mapped_column(Integer, primary_key=True)
+ user_id = mapped_column(Integer, ForeignKey('user.id'))
class User(Base):
__tablename__ = 'user'
- id = Column(Integer, primary_key=True)
+ id = mapped_column(Integer, primary_key=True)
address_count = column_property(
select(func.count(Address.id)).
where(Address.user_id==id).
@@ -159,10 +160,35 @@ being inadvertently omitted from the FROM list in the case of a long string
of joins between ``User`` and ``Address`` tables where SELECT statements against
``Address`` are nested.
+For a :func:`.column_property` that refers to columns linked from a
+many-to-many relationship, use :func:`.and_` to join the fields of the
+association table to both tables in a relationship::
+
+ from sqlalchemy import and_
+
+ class Author(Base):
+ # ...
+
+ book_count = column_property(
+ select(func.count(books.c.id)
+ ).where(
+ and_(
+ book_authors.c.author_id==authors.c.id,
+ book_authors.c.book_id==books.c.id
+ )
+ ).scalar_subquery()
+ )
+
+
+Adding column_property() to an existing Declarative mapped class
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
If import issues prevent the :func:`.column_property` from being defined
inline with the class, it can be assigned to the class after both
-are configured. When using mappings that make use of a :func:`_orm.declarative_base`
-base class, this attribute assignment has the effect of calling :meth:`_orm.Mapper.add_property`
+are configured. When using mappings that make use of a Declarative
+base class (i.e. produced by the :class:`_orm.DeclarativeBase` superclass
+or legacy functions such as :func:`_orm.declarative_base`),
+this attribute assignment has the effect of calling :meth:`_orm.Mapper.add_property`
to add an additional property after the fact::
# only works if a declarative base class is in use
@@ -172,7 +198,7 @@ to add an additional property after the fact::
scalar_subquery()
)
-When using mapping styles that don't use :func:`_orm.declarative_base`,
+When using mapping styles that don't use Declarative base classes
such as the :meth:`_orm.registry.mapped` decorator, the :meth:`_orm.Mapper.add_property`
method may be invoked explicitly on the underlying :class:`_orm.Mapper` object,
which can be obtained using :func:`_sa.inspect`::
@@ -200,24 +226,10 @@ which can be obtained using :func:`_sa.inspect`::
)
)
-For a :func:`.column_property` that refers to columns linked from a
-many-to-many relationship, use :func:`.and_` to join the fields of the
-association table to both tables in a relationship::
+.. seealso::
- from sqlalchemy import and_
+ :ref:`orm_declarative_table_adding_columns`
- class Author(Base):
- # ...
-
- book_count = column_property(
- select(func.count(books.c.id)
- ).where(
- and_(
- book_authors.c.author_id==authors.c.id,
- book_authors.c.book_id==books.c.id
- )
- ).scalar_subquery()
- )
.. _mapper_column_property_sql_expressions_composed:
@@ -241,9 +253,9 @@ attribute, which is itself a :class:`.ColumnProperty`::
class File(Base):
__tablename__ = 'file'
- id = Column(Integer, primary_key=True)
- name = Column(String(64))
- extension = Column(String(8))
+ id = mapped_column(Integer, primary_key=True)
+ name = mapped_column(String(64))
+ extension = mapped_column(String(8))
filename = column_property(name + '.' + extension)
path = column_property('C:/' + filename.expression)
@@ -254,6 +266,8 @@ the :class:`.ColumnProperty` directly within the mapping definition::
stmt = select(File.path).where(File.filename == 'foo.txt')
+.. autofunction:: column_property
+
Using a plain descriptor
------------------------
@@ -272,9 +286,9 @@ which is then used to emit a query::
class User(Base):
__tablename__ = 'user'
- id = Column(Integer, primary_key=True)
- firstname = Column(String(50))
- lastname = Column(String(50))
+ id = mapped_column(Integer, primary_key=True)
+ firstname = mapped_column(String(50))
+ lastname = mapped_column(String(50))
@property
def address_count(self):
@@ -313,9 +327,9 @@ may be applied::
class A(Base):
__tablename__ = 'a'
- id = Column(Integer, primary_key=True)
- x = Column(Integer)
- y = Column(Integer)
+ id = mapped_column(Integer, primary_key=True)
+ x = mapped_column(Integer)
+ y = mapped_column(Integer)
expr = query_expression()