From: Federico Caselli Date: Thu, 12 Jan 2023 22:06:54 +0000 (+0100) Subject: Remove old file and missing doc section X-Git-Tag: rel_2_0_0rc3~18^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1967b9507d9b8e5ca202ee567601e8647c3f965e;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Remove old file and missing doc section Change-Id: Ic6dda7f32a7561a0c0a92b8a7c08e44cb174eec1 --- diff --git a/doc/build/core/operators.rst b/doc/build/core/operators.rst index 84fc554fc6..891e5a3a10 100644 --- a/doc/build/core/operators.rst +++ b/doc/build/core/operators.rst @@ -696,14 +696,6 @@ The above conjunction functions :func:`_sql.and_`, :func:`_sql.or_`, .. - - -Operator Customization -^^^^^^^^^^^^^^^^^^^^^^ - -TODO - - .. Setup code, not for display >>> conn.close() diff --git a/doc/build/orm/queryguide/columns_scratch.txt b/doc/build/orm/queryguide/columns_scratch.txt deleted file mode 100644 index 5da164cea4..0000000000 --- a/doc/build/orm/queryguide/columns_scratch.txt +++ /dev/null @@ -1,471 +0,0 @@ - -this is the old content for reference while the new section is written - -remove when complete - - -The ORM loader option system supports the concept of "wildcard" loader options, -in which a loader option can be passed an asterisk ``"*"`` to indicate that -a particular option should apply to all applicable attributes of a mapped -class. Such as, if we wanted to load the ``Book`` class but only -the "summary" and "excerpt" columns, we could say:: - - from sqlalchemy.orm import defer - from sqlalchemy.orm import undefer - from sqlalchemy import select - - stmt = select(Book).options( - defer('*'), undefer(Book.summary), undefer(Book.excerpt)) - - book_objs = session.scalars(stmt).all() - -Above, the :func:`.defer` option is applied using a wildcard to all column -attributes on the ``Book`` class. Then, the :func:`.undefer` option is used -against the "summary" and "excerpt" fields so that they are the only columns -loaded up front. A query for the above entity will include only the "summary" -and "excerpt" fields in the SELECT, along with the primary key columns which -are always used by the ORM. - -A similar function is available with less verbosity by using the -:func:`_orm.load_only` option. This is a so-called **exclusionary** option -which will apply deferred behavior to all column attributes except those -that are named:: - - from sqlalchemy.orm import load_only - from sqlalchemy import select - - stmt = select(Book).options(load_only(Book.summary, Book.excerpt)) - - book_objs = session.scal - -Load Only and Wildcard Options ------------------------------- - -The ORM loader option system supports the concept of "wildcard" loader options, -in which a loader option can be passed an asterisk ``"*"`` to indicate that -a particular option should apply to all applicable attributes of a mapped -class. Such as, if we wanted to load the ``Book`` class but only -the "summary" and "excerpt" columns, we could say:: - - from sqlalchemy.orm import defer - from sqlalchemy.orm import undefer - from sqlalchemy import select - - stmt = select(Book).options( - defer('*'), undefer(Book.summary), undefer(Book.excerpt)) - - book_objs = session.scalars(stmt).all() - -Above, the :func:`.defer` option is applied using a wildcard to all column -attributes on the ``Book`` class. Then, the :func:`.undefer` option is used -against the "summary" and "excerpt" fields so that they are the only columns -loaded up front. A query for the above entity will include only the "summary" -and "excerpt" fields in the SELECT, along with the primary key columns which -are always used by the ORM. - -A similar function is available with less verbosity by using the -:func:`_orm.load_only` option. This is a so-called **exclusionary** option -which will apply deferred behavior to all column attributes except those -that are named:: - - from sqlalchemy.orm import load_only - from sqlalchemy import select - - stmt = select(Book).options(load_only(Book.summary, Book.excerpt)) - - book_objs = session.scalars(stmt).all() - -Wildcard and Exclusionary Options with Multiple-Entity Queries -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Wildcard options and exclusionary options such as :func:`.load_only` may -only be applied to a single entity at a time within a statement. -To suit the less common case where a statement is returning multiple -primary entities at once, a special calling style may be required in order -to apply a wildcard or exclusionary option to a specific entity, which is to use the -:class:`_orm.Load` object to indicate the starting entity for a deferral option. -Such as, if we were loading ``Book`` and ``Author`` at once, the ORM -will raise an informative error if we try to apply :func:`.load_only` to -both at once. Instead, we may use :class:`_orm.Load` to apply the option -to either or both of ``Book`` and ``Author`` individually:: - - from sqlalchemy.orm import Load - - stmt = select(Book, Author).join(Book.author) - stmt = stmt.options( - Load(Book).load_only(Book.summary, Book.excerpt) - ) - book_author_objs = session.execute(stmt).all() - -Above, :class:`_orm.Load` is used in conjunction with the exclusionary option -:func:`.load_only` so that the deferral of all other columns only takes -place for the ``Book`` class and not the ``Author`` class. Again, -the ORM should raise an informative error message when -the above calling style is actually required that describes those cases -where explicit use of :class:`_orm.Load` is needed. -ars(stmt).all() - -Wildcard and Exclusionary Options with Multiple-Entity Queries -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Wildcard options and exclusionary options such as :func:`.load_only` may -only be applied to a single entity at a time within a statement. -To suit the less common case where a statement is returning multiple -primary entities at once, a special calling style may be required in order -to apply a wildcard or exclusionary option to a specific entity, which is to use the -:class:`_orm.Load` object to indicate the starting entity for a deferral option. -Such as, if we were loading ``Book`` and ``Author`` at once, the ORM -will raise an informative error if we try to apply :func:`.load_only` to -both at once. Instead, we may use :class:`_orm.Load` to apply the option -to either or both of ``Book`` and ``Author`` individually:: - - from sqlalchemy.orm import Load - - stmt = select(Book, Author).join(Book.author) - stmt = stmt.options( - Load(Book).load_only(Book.summary, Book.excerpt) - ) - book_author_objs = session.execute(stmt).all() - -Above, :class:`_orm.Load` is used in conjunction with the exclusionary option -:func:`.load_only` so that the deferral of all other columns only takes -place for the ``Book`` class and not the ``Author`` class. Again, -the ORM should raise an informative error message when -the above calling style is actually required that describes those cases -where explicit use of :class:`_orm.Load` is needed. - - - - -Deferred Column Loading -======================= - -Deferred column loading allows particular columns of a table be loaded only -upon direct access, instead of when the entity is queried using -:class:`_sql.Select` or :class:`_orm.Query`. This feature is useful when one wants to avoid -loading a large text or binary field into memory when it's not needed. - -Configuring Deferred Loading at Mapper Configuration Time ---------------------------------------------------------- - -First introduced at :ref:`orm_declarative_column_options` and -:ref:`orm_imperative_table_column_options`, the -:paramref:`_orm.mapped_column.deferred` parameter of :func:`_orm.mapped_column`, -as well as the :func:`_orm.deferred` ORM function may be used to indicate mapped -columns as "deferred" at mapper configuration time. With this configuration, -the target columns will not be loaded in SELECT statements by default, and -will instead only be loaded "lazily" when their corresponding attribute is -accessed on a mapped instance. Deferral can be configured for individual -columns or groups of columns that will load together when any of them -are accessed. - -In the example below, using :ref:`Declarative Table ` -configuration, we define a mapping that will load each of -``.excerpt`` and ``.photo`` in separate, individual-row SELECT statements when each -attribute is first referenced on the individual object instance:: - - from sqlalchemy import Text - from sqlalchemy.orm import DeclarativeBase - from sqlalchemy.orm import Mapped - from sqlalchemy.orm import mapped_column - - class Base(DeclarativeBase): - pass - - class Book(Base): - __tablename__ = 'book' - - book_id: Mapped[int] = mapped_column(primary_key=True) - title: Mapped[str] - summary: Mapped[str] - excerpt: Mapped[str] = mapped_column(Text, deferred=True) - photo: Mapped[bytes] = mapped_column(deferred=True) - -A :func:`_sql.select` construct for the above mapping will not include -``excerpt`` and ``photo`` by default:: - - >>> from sqlalchemy import select - >>> print(select(Book)) - SELECT book.book_id, book.title, book.summary - FROM book - -When an object of type ``Book`` is loaded by the ORM, accessing the -``.excerpt`` or ``.photo`` attributes will instead :term:`lazy load` the -data from each column using a new SQL statement. - -When using :ref:`Imperative Table ` -or fully :ref:`Imperative ` configuration, the -:func:`_orm.deferred` construct should be used instead, passing the -target :class:`_schema.Column` object to be mapped as the argument:: - - from sqlalchemy import Column, Integer, LargeBinary, String, Table, Text - from sqlalchemy.orm import DeclarativeBase - from sqlalchemy.orm import deferred - - - class Base(DeclarativeBase): - pass - - - book = Table( - "book", - Base.metadata, - Column("book_id", Integer, primary_key=True), - Column("title", String), - Column("summary", String), - Column("excerpt", Text), - Column("photo", LargeBinary), - ) - - - class Book(Base): - __table__ = book - - excerpt = deferred(book.c.excerpt) - photo = deferred(book.c.photo) - - -Deferred columns can be associated with a "group" name, so that they load -together when any of them are first accessed. When using -:func:`_orm.mapped_column`, this group name may be specified using the -:paramref:`_orm.mapped_column.deferred_group` parameter, which implies -:paramref:`_orm.mapped_column.deferred` if that parameter is not already -set. When using :func:`_orm.deferred`, the :paramref:`_orm.deferred.group` -parameter may be used. - -The example below defines a mapping with a ``photos`` deferred group. When -an attribute within the group ``.photo1``, ``.photo2``, ``.photo3`` -is accessed on an instance of ``Book``, all three columns will be loaded in one SELECT -statement. The ``.excerpt`` column however will only be loaded when it -is directly accessed:: - - from sqlalchemy import Text - from sqlalchemy.orm import DeclarativeBase - from sqlalchemy.orm import Mapped - from sqlalchemy.orm import mapped_column - - class Base(DeclarativeBase): - pass - - class Book(Base): - __tablename__ = 'book' - - book_id: Mapped[int] = mapped_column(primary_key=True) - title: Mapped[str] - summary: Mapped[str] - excerpt: Mapped[str] = mapped_column(Text, deferred=True) - photo1: Mapped[bytes] = mapped_column(deferred_group="photos") - photo2: Mapped[bytes] = mapped_column(deferred_group="photos") - photo3: Mapped[bytes] = mapped_column(deferred_group="photos") - - -.. _deferred_options: - -Deferred Column Loader Query Options ------------------------------------- -At query time, the :func:`_orm.defer`, :func:`_orm.undefer` and -:func:`_orm.undefer_group` loader options may be used to further control the -"deferral behavior" of mapped columns. - -Columns can be marked as "deferred" or reset to "undeferred" at query time -using options which are passed to the :meth:`_sql.Select.options` method; the most -basic query options are :func:`_orm.defer` and -:func:`_orm.undefer`:: - - from sqlalchemy.orm import defer - from sqlalchemy.orm import undefer - from sqlalchemy import select - - stmt = select(Book) - stmt = stmt.options(defer(Book.summary), undefer(Book.excerpt)) - book_objs = session.scalars(stmt).all() - - -Above, the "summary" column will not load until accessed, and the "excerpt" -column will load immediately even if it was mapped as a "deferred" column. - -:func:`_orm.deferred` attributes which are marked with a "group" can be undeferred -using :func:`_orm.undefer_group`, sending in the group name:: - - from sqlalchemy.orm import undefer_group - from sqlalchemy import select - - stmt = select(Book) - stmt = stmt.options(undefer_group('photos')) - book_objs = session.scalars(stmt).all() - - -.. _deferred_loading_w_multiple: - -Deferred Loading across Multiple Entities ------------------------------------------ - -Column deferral may also be used for a statement that loads multiple types of -entities at once, by referring to the appropriate class bound attribute -within the :func:`_orm.defer` function. Suppose ``Book`` has a -relationship ``Book.author`` to a related class ``Author``, we could write -a query as follows which will defer the ``Author.bio`` column:: - - from sqlalchemy.orm import defer - from sqlalchemy import select - - stmt = select(Book, Author).join(Book.author) - stmt = stmt.options(defer(Author.bio)) - - book_author_objs = session.execute(stmt).all() - - -Column deferral options may also indicate that they take place along various -relationship paths, which are themselves often :ref:`eagerly loaded -` with loader options. All relationship-bound loader options -support chaining onto additional loader options, which include loading for -further levels of relationships, as well as onto column-oriented attributes at -that path. Such as, to load ``Author`` instances, then joined-eager-load the -``Author.books`` collection for each author, then apply deferral options to -column-oriented attributes onto each ``Book`` entity from that relationship, -the :func:`_orm.joinedload` loader option can be combined with the :func:`.load_only` -option (described later in this section) to defer all ``Book`` columns except -those explicitly specified:: - - from sqlalchemy.orm import joinedload - from sqlalchemy import select - - stmt = select(Author) - stmt = stmt.options( - joinedload(Author.books).load_only(Book.summary, Book.excerpt) - ) - - author_objs = session.scalars(stmt).all() - -Option structures as above can also be organized in more complex ways, such -as hierarchically using the :meth:`_orm.Load.options` -method, which allows multiple sub-options to be chained to a common parent -option at once. The example below illustrates a more complex structure:: - - from sqlalchemy.orm import defer - from sqlalchemy.orm import joinedload - from sqlalchemy.orm import load_only - from sqlalchemy import select - - stmt = select(Author) - stmt = stmt.options( - joinedload(Author.book).options( - load_only(Book.summary, Book.excerpt), - joinedload(Book.citations).options( - joinedload(Citation.author), - defer(Citation.fulltext) - ) - ) - ) - author_objs = session.scalars(stmt).all() - - -Another way to apply options to a path is to use the :func:`_orm.defaultload` -function. This function is used to indicate a particular path within a loader -option structure without actually setting any options at that level, so that further -sub-options may be applied. The :func:`_orm.defaultload` function can be used -to create the same structure as we did above using :meth:`_orm.Load.options` as:: - - from sqlalchemy import select - from sqlalchemy.orm import defaultload - - stmt = select(Author) - stmt = stmt.options( - joinedload(Author.book).load_only(Book.summary, Book.excerpt), - defaultload(Author.book).joinedload(Book.citations).joinedload(Citation.author), - defaultload(Author.book).defaultload(Book.citations).defer(Citation.fulltext) - ) - - author_objs = session.scalars(stmt).all() - -.. seealso:: - - :ref:`relationship_loader_options` - targeted towards relationship loading - - -.. _deferred_raiseload: - -Raiseload for Deferred Columns ------------------------------- - -.. versionadded:: 1.4 - -The :func:`.deferred` loader option and the corresponding loader strategy also -support the concept of "raiseload", which is a loader strategy that will raise -:class:`.InvalidRequestError` if the attribute is accessed such that it would -need to emit a SQL query in order to be loaded. This behavior is the -column-based equivalent of the :func:`_orm.raiseload` feature for relationship -loading, discussed at :ref:`prevent_lazy_with_raiseload`. Using the -:paramref:`_orm.defer.raiseload` parameter on the :func:`_orm.defer` option, -an exception is raised if the attribute is accessed:: - - book = session.scalar( - select(Book).options(defer(Book.summary, raiseload=True)).limit(1) - ) - - # would raise an exception - book.summary - -Deferred "raiseload" can be configured at the mapper level via -:paramref:`.orm.deferred.raiseload` on either :func:`_orm.mapped_column` -or in :func:`.deferred`, so that an explicit -:func:`.undefer` is required in order for the attribute to be usable. -Below is a :ref:`Declarative table ` configuration example:: - - - from sqlalchemy import Text - from sqlalchemy.orm import DeclarativeBase - from sqlalchemy.orm import Mapped - from sqlalchemy.orm import mapped_column - - class Base(DeclarativeBase): - pass - - class Book(Base): - __tablename__ = 'book' - - book_id: Mapped[int] = mapped_column(primary_key=True) - title: Mapped[str] - summary: Mapped[str] = mapped_column(raiseload=True) - excerpt: Mapped[str] = mapped_column(Text, raiseload=True) - -Alternatively, the example below illustrates the same mapping using a -:ref:`Imperative table ` configuration:: - - from sqlalchemy import Column, Integer, LargeBinary, String, Table, Text - from sqlalchemy.orm import DeclarativeBase - from sqlalchemy.orm import deferred - - - class Base(DeclarativeBase): - pass - - - book = Table( - "book", - Base.metadata, - Column("book_id", Integer, primary_key=True), - Column("title", String), - Column("summary", String), - Column("excerpt", Text), - ) - - - class Book(Base): - __table__ = book - - summary = deferred(book.c.summary, raiseload=True) - excerpt = deferred(book.c.excerpt, raiseload=True) - -With both mappings, if we wish to have either or both of ``.excerpt`` -or ``.summary`` available on an object when loaded, we make use of the -:func:`_orm.undefer` loader option:: - - book_w_excerpt = session.scalars( - select(Book).options(undefer(Book.excerpt)).where(Book.id == 12) - ).first() - -The :func:`_orm.undefer` option will populate the ``.excerpt`` attribute -above, even if the ``Book`` object were already loaded, assuming the -``.excerpt`` field was not populated by some other means previously. -