about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/sqlalchemy/ext/declarative
diff options
context:
space:
mode:
authorS. Solomon Darnell2025-03-28 21:52:21 -0500
committerS. Solomon Darnell2025-03-28 21:52:21 -0500
commit4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch)
treeee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/sqlalchemy/ext/declarative
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-master.tar.gz
two version of R2R are here HEAD master
Diffstat (limited to '.venv/lib/python3.12/site-packages/sqlalchemy/ext/declarative')
-rw-r--r--.venv/lib/python3.12/site-packages/sqlalchemy/ext/declarative/__init__.py65
-rw-r--r--.venv/lib/python3.12/site-packages/sqlalchemy/ext/declarative/extensions.py564
2 files changed, 629 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/sqlalchemy/ext/declarative/__init__.py b/.venv/lib/python3.12/site-packages/sqlalchemy/ext/declarative/__init__.py
new file mode 100644
index 00000000..0383f9d3
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/sqlalchemy/ext/declarative/__init__.py
@@ -0,0 +1,65 @@
+# ext/declarative/__init__.py
+# Copyright (C) 2005-2025 the SQLAlchemy authors and contributors
+# <see AUTHORS file>
+#
+# This module is part of SQLAlchemy and is released under
+# the MIT License: https://www.opensource.org/licenses/mit-license.php
+# mypy: ignore-errors
+
+
+from .extensions import AbstractConcreteBase
+from .extensions import ConcreteBase
+from .extensions import DeferredReflection
+from ... import util
+from ...orm.decl_api import as_declarative as _as_declarative
+from ...orm.decl_api import declarative_base as _declarative_base
+from ...orm.decl_api import DeclarativeMeta
+from ...orm.decl_api import declared_attr
+from ...orm.decl_api import has_inherited_table as _has_inherited_table
+from ...orm.decl_api import synonym_for as _synonym_for
+
+
+@util.moved_20(
+    "The ``declarative_base()`` function is now available as "
+    ":func:`sqlalchemy.orm.declarative_base`."
+)
+def declarative_base(*arg, **kw):
+    return _declarative_base(*arg, **kw)
+
+
+@util.moved_20(
+    "The ``as_declarative()`` function is now available as "
+    ":func:`sqlalchemy.orm.as_declarative`"
+)
+def as_declarative(*arg, **kw):
+    return _as_declarative(*arg, **kw)
+
+
+@util.moved_20(
+    "The ``has_inherited_table()`` function is now available as "
+    ":func:`sqlalchemy.orm.has_inherited_table`."
+)
+def has_inherited_table(*arg, **kw):
+    return _has_inherited_table(*arg, **kw)
+
+
+@util.moved_20(
+    "The ``synonym_for()`` function is now available as "
+    ":func:`sqlalchemy.orm.synonym_for`"
+)
+def synonym_for(*arg, **kw):
+    return _synonym_for(*arg, **kw)
+
+
+__all__ = [
+    "declarative_base",
+    "synonym_for",
+    "has_inherited_table",
+    "instrument_declarative",
+    "declared_attr",
+    "as_declarative",
+    "ConcreteBase",
+    "AbstractConcreteBase",
+    "DeclarativeMeta",
+    "DeferredReflection",
+]
diff --git a/.venv/lib/python3.12/site-packages/sqlalchemy/ext/declarative/extensions.py b/.venv/lib/python3.12/site-packages/sqlalchemy/ext/declarative/extensions.py
new file mode 100644
index 00000000..3dc6bf69
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/sqlalchemy/ext/declarative/extensions.py
@@ -0,0 +1,564 @@
+# ext/declarative/extensions.py
+# Copyright (C) 2005-2025 the SQLAlchemy authors and contributors
+# <see AUTHORS file>
+#
+# This module is part of SQLAlchemy and is released under
+# the MIT License: https://www.opensource.org/licenses/mit-license.php
+# mypy: ignore-errors
+
+
+"""Public API functions and helpers for declarative."""
+from __future__ import annotations
+
+import collections
+import contextlib
+from typing import Any
+from typing import Callable
+from typing import TYPE_CHECKING
+from typing import Union
+
+from ... import exc as sa_exc
+from ...engine import Connection
+from ...engine import Engine
+from ...orm import exc as orm_exc
+from ...orm import relationships
+from ...orm.base import _mapper_or_none
+from ...orm.clsregistry import _resolver
+from ...orm.decl_base import _DeferredMapperConfig
+from ...orm.util import polymorphic_union
+from ...schema import Table
+from ...util import OrderedDict
+
+if TYPE_CHECKING:
+    from ...sql.schema import MetaData
+
+
+class ConcreteBase:
+    """A helper class for 'concrete' declarative mappings.
+
+    :class:`.ConcreteBase` will use the :func:`.polymorphic_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 the :meth:`.after_configured` event.
+
+    :class:`.ConcreteBase` produces a mapped
+    table for the class itself.  Compare to :class:`.AbstractConcreteBase`,
+    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 :func:`.polymorphic_union`
+    defaults to the name ``type``.  To suit the use case of a mapping where an
+    actual column in a mapped table is already named ``type``, the
+    discriminator name can be configured by setting the
+    ``_concrete_discriminator_name`` attribute::
+
+        class Employee(ConcreteBase, Base):
+            _concrete_discriminator_name = "_concrete_discriminator"
+
+    .. versionadded:: 1.3.19 Added the ``_concrete_discriminator_name``
+       attribute to :class:`_declarative.ConcreteBase` so that the
+       virtual discriminator column name can be customized.
+
+    .. versionchanged:: 1.4.2 The ``_concrete_discriminator_name`` attribute
+       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.
+
+    .. seealso::
+
+        :class:`.AbstractConcreteBase`
+
+        :ref:`concrete_inheritance`
+
+
+    """
+
+    @classmethod
+    def _create_polymorphic_union(cls, mappers, discriminator_name):
+        return polymorphic_union(
+            OrderedDict(
+                (mp.polymorphic_identity, mp.local_table) for mp in mappers
+            ),
+            discriminator_name,
+            "pjoin",
+        )
+
+    @classmethod
+    def __declare_first__(cls):
+        m = cls.__mapper__
+        if m.with_polymorphic:
+            return
+
+        discriminator_name = (
+            getattr(cls, "_concrete_discriminator_name", None) or "type"
+        )
+
+        mappers = list(m.self_and_descendants)
+        pjoin = cls._create_polymorphic_union(mappers, discriminator_name)
+        m._set_with_polymorphic(("*", pjoin))
+        m._set_polymorphic_on(pjoin.c[discriminator_name])
+
+
+class AbstractConcreteBase(ConcreteBase):
+    """A helper class for 'concrete' declarative mappings.
+
+    :class:`.AbstractConcreteBase` will use the :func:`.polymorphic_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 the :meth:`.before_configured` event.
+
+    :class:`.AbstractConcreteBase` applies :class:`_orm.Mapper` for its
+    immediately inheriting class, as would occur for any other
+    declarative mapped class. However, the :class:`_orm.Mapper` is not
+    mapped to any particular :class:`.Table` object.  Instead, it's
+    mapped directly to the "polymorphic" selectable produced by
+    :func:`.polymorphic_union`, and performs no persistence operations on its
+    own.  Compare to :class:`.ConcreteBase`, which maps its
+    immediately inheriting class to an actual
+    :class:`.Table` that stores rows directly.
+
+    .. note::
+
+        The :class:`.AbstractConcreteBase` delays 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
+        :class:`.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, the
+        :meth:`_orm.registry.configure` method on the :class:`_orm.registry`
+        in 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 :ref:`declarative_mixins`::
+
+        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 ``Manager`` and
+    ``Employee`` will have an independently usable ``.company`` attribute::
+
+        session.execute(select(Employee).filter(Employee.company.has(id=5)))
+
+    :param 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.
+
+     .. versionadded:: 2.0
+
+    .. seealso::
+
+        :class:`.ConcreteBase`
+
+        :ref:`concrete_inheritance`
+
+        :ref:`abstract_concrete_base`
+
+    """
+
+    __no_table__ = True
+
+    @classmethod
+    def __declare_first__(cls):
+        cls._sa_decl_prepare_nocascade()
+
+    @classmethod
+    def _sa_decl_prepare_nocascade(cls):
+        if getattr(cls, "__mapper__", None):
+            return
+
+        to_map = _DeferredMapperConfig.config_for_cls(cls)
+
+        # can't rely on 'self_and_descendants' here
+        # since technically an immediate subclass
+        # might not be mapped, but a subclass
+        # may be.
+        mappers = []
+        stack = list(cls.__subclasses__())
+        while stack:
+            klass = stack.pop()
+            stack.extend(klass.__subclasses__())
+            mn = _mapper_or_none(klass)
+            if mn is not None:
+                mappers.append(mn)
+
+        discriminator_name = (
+            getattr(cls, "_concrete_discriminator_name", None) or "type"
+        )
+        pjoin = cls._create_polymorphic_union(mappers, discriminator_name)
+
+        # For columns that were declared on the class, these
+        # are normally ignored with the "__no_table__" mapping,
+        # unless they have a different attribute key vs. col name
+        # and are in the properties argument.
+        # In that case, ensure we update the properties entry
+        # to the correct column from the pjoin target table.
+        declared_cols = set(to_map.declared_columns)
+        declared_col_keys = {c.key for c in declared_cols}
+        for k, v in list(to_map.properties.items()):
+            if v in declared_cols:
+                to_map.properties[k] = pjoin.c[v.key]
+                declared_col_keys.remove(v.key)
+
+        to_map.local_table = pjoin
+
+        strict_attrs = cls.__dict__.get("strict_attrs", False)
+
+        m_args = to_map.mapper_args_fn or dict
+
+        def mapper_args():
+            args = m_args()
+            args["polymorphic_on"] = pjoin.c[discriminator_name]
+            args["polymorphic_abstract"] = True
+            if strict_attrs:
+                args["include_properties"] = (
+                    set(pjoin.primary_key)
+                    | declared_col_keys
+                    | {discriminator_name}
+                )
+                args["with_polymorphic"] = ("*", pjoin)
+            return args
+
+        to_map.mapper_args_fn = mapper_args
+
+        to_map.map()
+
+        stack = [cls]
+        while stack:
+            scls = stack.pop(0)
+            stack.extend(scls.__subclasses__())
+            sm = _mapper_or_none(scls)
+            if sm and sm.concrete and sm.inherits is None:
+                for sup_ in scls.__mro__[1:]:
+                    sup_sm = _mapper_or_none(sup_)
+                    if sup_sm:
+                        sm._set_concrete_base(sup_sm)
+                        break
+
+    @classmethod
+    def _sa_raise_deferred_config(cls):
+        raise orm_exc.UnmappedClassError(
+            cls,
+            msg="Class %s is a subclass of AbstractConcreteBase and "
+            "has a mapping pending until all subclasses are defined. "
+            "Call the sqlalchemy.orm.configure_mappers() function after "
+            "all subclasses have been defined to "
+            "complete the mapping of this class."
+            % orm_exc._safe_cls_name(cls),
+        )
+
+
+class DeferredReflection:
+    """A helper class for construction of mappings based on
+    a deferred reflection step.
+
+    Normally, declarative can be used with reflection by
+    setting a :class:`_schema.Table` object using autoload_with=engine
+    as the ``__table__`` attribute on a declarative class.
+    The caveat is that the :class:`_schema.Table` must 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 the :class:`_engine.Engine` must be available
+    at class declaration time.
+
+    The :class:`.DeferredReflection` mixin moves the construction
+    of mappers to be at a later point, after a specific
+    method is called which first reflects all :class:`_schema.Table`
+    objects 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, ``MyClass`` is not yet mapped.   After a series of
+    classes have been defined in the above fashion, all tables
+    can be reflected and mappings created using
+    :meth:`.prepare`::
+
+        engine = create_engine("someengine://...")
+        DeferredReflection.prepare(engine)
+
+    The :class:`.DeferredReflection` mixin 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 ``ReflectedOne`` and
+    ``ReflectedTwo`` can be configured separately::
+
+        ReflectedOne.prepare(engine_one)
+        ReflectedTwo.prepare(engine_two)
+
+    .. seealso::
+
+        :ref:`orm_declarative_reflected_deferred_reflection` - in the
+        :ref:`orm_declarative_table_config_toplevel` section.
+
+    """
+
+    @classmethod
+    def prepare(
+        cls, bind: Union[Engine, Connection], **reflect_kw: Any
+    ) -> None:
+        r"""Reflect all :class:`_schema.Table` objects for all current
+        :class:`.DeferredReflection` subclasses
+
+        :param bind: :class:`_engine.Engine` or :class:`_engine.Connection`
+         instance
+
+         ..versionchanged:: 2.0.16 a :class:`_engine.Connection` is also
+         accepted.
+
+        :param \**reflect_kw: additional keyword arguments passed to
+         :meth:`_schema.MetaData.reflect`, such as
+         :paramref:`_schema.MetaData.reflect.views`.
+
+         .. versionadded:: 2.0.16
+
+        """
+
+        to_map = _DeferredMapperConfig.classes_for_base(cls)
+
+        metadata_to_table = collections.defaultdict(set)
+
+        # first collect the primary __table__ for each class into a
+        # collection of metadata/schemaname -> table names
+        for thingy in to_map:
+            if thingy.local_table is not None:
+                metadata_to_table[
+                    (thingy.local_table.metadata, thingy.local_table.schema)
+                ].add(thingy.local_table.name)
+
+        # then reflect all those tables into their metadatas
+
+        if isinstance(bind, Connection):
+            conn = bind
+            ctx = contextlib.nullcontext(enter_result=conn)
+        elif isinstance(bind, Engine):
+            ctx = bind.connect()
+        else:
+            raise sa_exc.ArgumentError(
+                f"Expected Engine or Connection, got {bind!r}"
+            )
+
+        with ctx as conn:
+            for (metadata, schema), table_names in metadata_to_table.items():
+                metadata.reflect(
+                    conn,
+                    only=table_names,
+                    schema=schema,
+                    extend_existing=True,
+                    autoload_replace=False,
+                    **reflect_kw,
+                )
+
+            metadata_to_table.clear()
+
+            # .map() each class, then go through relationships and look
+            # for secondary
+            for thingy in to_map:
+                thingy.map()
+
+                mapper = thingy.cls.__mapper__
+                metadata = mapper.class_.metadata
+
+                for rel in mapper._props.values():
+                    if (
+                        isinstance(rel, relationships.RelationshipProperty)
+                        and rel._init_args.secondary._is_populated()
+                    ):
+                        secondary_arg = rel._init_args.secondary
+
+                        if isinstance(secondary_arg.argument, Table):
+                            secondary_table = secondary_arg.argument
+                            metadata_to_table[
+                                (
+                                    secondary_table.metadata,
+                                    secondary_table.schema,
+                                )
+                            ].add(secondary_table.name)
+                        elif isinstance(secondary_arg.argument, str):
+                            _, resolve_arg = _resolver(rel.parent.class_, rel)
+
+                            resolver = resolve_arg(
+                                secondary_arg.argument, True
+                            )
+                            metadata_to_table[
+                                (metadata, thingy.local_table.schema)
+                            ].add(secondary_arg.argument)
+
+                            resolver._resolvers += (
+                                cls._sa_deferred_table_resolver(metadata),
+                            )
+
+                            secondary_arg.argument = resolver()
+
+            for (metadata, schema), table_names in metadata_to_table.items():
+                metadata.reflect(
+                    conn,
+                    only=table_names,
+                    schema=schema,
+                    extend_existing=True,
+                    autoload_replace=False,
+                )
+
+    @classmethod
+    def _sa_deferred_table_resolver(
+        cls, metadata: MetaData
+    ) -> Callable[[str], Table]:
+        def _resolve(key: str) -> Table:
+            # reflection has already occurred so this Table would have
+            # its contents already
+            return Table(key, metadata)
+
+        return _resolve
+
+    _sa_decl_prepare = True
+
+    @classmethod
+    def _sa_raise_deferred_config(cls):
+        raise orm_exc.UnmappedClassError(
+            cls,
+            msg="Class %s is a subclass of DeferredReflection.  "
+            "Mappings are not produced until the .prepare() "
+            "method is called on the class hierarchy."
+            % orm_exc._safe_cls_name(cls),
+        )