Загрузить файлы в «venv/Lib/site-packages/sqlalchemy»
This commit is contained in:
283
venv/Lib/site-packages/sqlalchemy/__init__.py
Normal file
283
venv/Lib/site-packages/sqlalchemy/__init__.py
Normal file
@@ -0,0 +1,283 @@
|
||||
# __init__.py
|
||||
# Copyright (C) 2005-2026 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
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from . import util as _util
|
||||
from .engine import AdaptedConnection as AdaptedConnection
|
||||
from .engine import BaseRow as BaseRow
|
||||
from .engine import BindTyping as BindTyping
|
||||
from .engine import ChunkedIteratorResult as ChunkedIteratorResult
|
||||
from .engine import Compiled as Compiled
|
||||
from .engine import Connection as Connection
|
||||
from .engine import create_engine as create_engine
|
||||
from .engine import create_mock_engine as create_mock_engine
|
||||
from .engine import create_pool_from_url as create_pool_from_url
|
||||
from .engine import CreateEnginePlugin as CreateEnginePlugin
|
||||
from .engine import CursorResult as CursorResult
|
||||
from .engine import Dialect as Dialect
|
||||
from .engine import Engine as Engine
|
||||
from .engine import engine_from_config as engine_from_config
|
||||
from .engine import ExceptionContext as ExceptionContext
|
||||
from .engine import ExecutionContext as ExecutionContext
|
||||
from .engine import FrozenResult as FrozenResult
|
||||
from .engine import Inspector as Inspector
|
||||
from .engine import IteratorResult as IteratorResult
|
||||
from .engine import make_url as make_url
|
||||
from .engine import MappingResult as MappingResult
|
||||
from .engine import MergedResult as MergedResult
|
||||
from .engine import NestedTransaction as NestedTransaction
|
||||
from .engine import Result as Result
|
||||
from .engine import result_tuple as result_tuple
|
||||
from .engine import ResultProxy as ResultProxy
|
||||
from .engine import RootTransaction as RootTransaction
|
||||
from .engine import Row as Row
|
||||
from .engine import RowMapping as RowMapping
|
||||
from .engine import ScalarResult as ScalarResult
|
||||
from .engine import Transaction as Transaction
|
||||
from .engine import TwoPhaseTransaction as TwoPhaseTransaction
|
||||
from .engine import TypeCompiler as TypeCompiler
|
||||
from .engine import URL as URL
|
||||
from .inspection import inspect as inspect
|
||||
from .pool import AssertionPool as AssertionPool
|
||||
from .pool import AsyncAdaptedQueuePool as AsyncAdaptedQueuePool
|
||||
from .pool import (
|
||||
FallbackAsyncAdaptedQueuePool as FallbackAsyncAdaptedQueuePool,
|
||||
)
|
||||
from .pool import NullPool as NullPool
|
||||
from .pool import Pool as Pool
|
||||
from .pool import PoolProxiedConnection as PoolProxiedConnection
|
||||
from .pool import PoolResetState as PoolResetState
|
||||
from .pool import QueuePool as QueuePool
|
||||
from .pool import SingletonThreadPool as SingletonThreadPool
|
||||
from .pool import StaticPool as StaticPool
|
||||
from .schema import BaseDDLElement as BaseDDLElement
|
||||
from .schema import BLANK_SCHEMA as BLANK_SCHEMA
|
||||
from .schema import CheckConstraint as CheckConstraint
|
||||
from .schema import Column as Column
|
||||
from .schema import ColumnDefault as ColumnDefault
|
||||
from .schema import Computed as Computed
|
||||
from .schema import Constraint as Constraint
|
||||
from .schema import DDL as DDL
|
||||
from .schema import DDLElement as DDLElement
|
||||
from .schema import DefaultClause as DefaultClause
|
||||
from .schema import ExecutableDDLElement as ExecutableDDLElement
|
||||
from .schema import FetchedValue as FetchedValue
|
||||
from .schema import ForeignKey as ForeignKey
|
||||
from .schema import ForeignKeyConstraint as ForeignKeyConstraint
|
||||
from .schema import Identity as Identity
|
||||
from .schema import Index as Index
|
||||
from .schema import insert_sentinel as insert_sentinel
|
||||
from .schema import MetaData as MetaData
|
||||
from .schema import PrimaryKeyConstraint as PrimaryKeyConstraint
|
||||
from .schema import Sequence as Sequence
|
||||
from .schema import Table as Table
|
||||
from .schema import UniqueConstraint as UniqueConstraint
|
||||
from .sql import ColumnExpressionArgument as ColumnExpressionArgument
|
||||
from .sql import NotNullable as NotNullable
|
||||
from .sql import Nullable as Nullable
|
||||
from .sql import SelectLabelStyle as SelectLabelStyle
|
||||
from .sql.expression import Alias as Alias
|
||||
from .sql.expression import alias as alias
|
||||
from .sql.expression import AliasedReturnsRows as AliasedReturnsRows
|
||||
from .sql.expression import all_ as all_
|
||||
from .sql.expression import and_ as and_
|
||||
from .sql.expression import any_ as any_
|
||||
from .sql.expression import asc as asc
|
||||
from .sql.expression import between as between
|
||||
from .sql.expression import BinaryExpression as BinaryExpression
|
||||
from .sql.expression import bindparam as bindparam
|
||||
from .sql.expression import BindParameter as BindParameter
|
||||
from .sql.expression import bitwise_not as bitwise_not
|
||||
from .sql.expression import BooleanClauseList as BooleanClauseList
|
||||
from .sql.expression import CacheKey as CacheKey
|
||||
from .sql.expression import Case as Case
|
||||
from .sql.expression import case as case
|
||||
from .sql.expression import Cast as Cast
|
||||
from .sql.expression import cast as cast
|
||||
from .sql.expression import ClauseElement as ClauseElement
|
||||
from .sql.expression import ClauseList as ClauseList
|
||||
from .sql.expression import collate as collate
|
||||
from .sql.expression import CollectionAggregate as CollectionAggregate
|
||||
from .sql.expression import column as column
|
||||
from .sql.expression import ColumnClause as ColumnClause
|
||||
from .sql.expression import ColumnCollection as ColumnCollection
|
||||
from .sql.expression import ColumnElement as ColumnElement
|
||||
from .sql.expression import ColumnOperators as ColumnOperators
|
||||
from .sql.expression import CompoundSelect as CompoundSelect
|
||||
from .sql.expression import CTE as CTE
|
||||
from .sql.expression import cte as cte
|
||||
from .sql.expression import custom_op as custom_op
|
||||
from .sql.expression import Delete as Delete
|
||||
from .sql.expression import delete as delete
|
||||
from .sql.expression import desc as desc
|
||||
from .sql.expression import distinct as distinct
|
||||
from .sql.expression import except_ as except_
|
||||
from .sql.expression import except_all as except_all
|
||||
from .sql.expression import Executable as Executable
|
||||
from .sql.expression import Exists as Exists
|
||||
from .sql.expression import exists as exists
|
||||
from .sql.expression import Extract as Extract
|
||||
from .sql.expression import extract as extract
|
||||
from .sql.expression import false as false
|
||||
from .sql.expression import False_ as False_
|
||||
from .sql.expression import FromClause as FromClause
|
||||
from .sql.expression import FromGrouping as FromGrouping
|
||||
from .sql.expression import func as func
|
||||
from .sql.expression import funcfilter as funcfilter
|
||||
from .sql.expression import Function as Function
|
||||
from .sql.expression import FunctionElement as FunctionElement
|
||||
from .sql.expression import FunctionFilter as FunctionFilter
|
||||
from .sql.expression import GenerativeSelect as GenerativeSelect
|
||||
from .sql.expression import Grouping as Grouping
|
||||
from .sql.expression import HasCTE as HasCTE
|
||||
from .sql.expression import HasPrefixes as HasPrefixes
|
||||
from .sql.expression import HasSuffixes as HasSuffixes
|
||||
from .sql.expression import Insert as Insert
|
||||
from .sql.expression import insert as insert
|
||||
from .sql.expression import intersect as intersect
|
||||
from .sql.expression import intersect_all as intersect_all
|
||||
from .sql.expression import Join as Join
|
||||
from .sql.expression import join as join
|
||||
from .sql.expression import Label as Label
|
||||
from .sql.expression import label as label
|
||||
from .sql.expression import LABEL_STYLE_DEFAULT as LABEL_STYLE_DEFAULT
|
||||
from .sql.expression import (
|
||||
LABEL_STYLE_DISAMBIGUATE_ONLY as LABEL_STYLE_DISAMBIGUATE_ONLY,
|
||||
)
|
||||
from .sql.expression import LABEL_STYLE_NONE as LABEL_STYLE_NONE
|
||||
from .sql.expression import (
|
||||
LABEL_STYLE_TABLENAME_PLUS_COL as LABEL_STYLE_TABLENAME_PLUS_COL,
|
||||
)
|
||||
from .sql.expression import lambda_stmt as lambda_stmt
|
||||
from .sql.expression import LambdaElement as LambdaElement
|
||||
from .sql.expression import Lateral as Lateral
|
||||
from .sql.expression import lateral as lateral
|
||||
from .sql.expression import literal as literal
|
||||
from .sql.expression import literal_column as literal_column
|
||||
from .sql.expression import modifier as modifier
|
||||
from .sql.expression import not_ as not_
|
||||
from .sql.expression import Null as Null
|
||||
from .sql.expression import null as null
|
||||
from .sql.expression import nulls_first as nulls_first
|
||||
from .sql.expression import nulls_last as nulls_last
|
||||
from .sql.expression import nullsfirst as nullsfirst
|
||||
from .sql.expression import nullslast as nullslast
|
||||
from .sql.expression import Operators as Operators
|
||||
from .sql.expression import or_ as or_
|
||||
from .sql.expression import outerjoin as outerjoin
|
||||
from .sql.expression import outparam as outparam
|
||||
from .sql.expression import Over as Over
|
||||
from .sql.expression import over as over
|
||||
from .sql.expression import quoted_name as quoted_name
|
||||
from .sql.expression import ReleaseSavepointClause as ReleaseSavepointClause
|
||||
from .sql.expression import ReturnsRows as ReturnsRows
|
||||
from .sql.expression import (
|
||||
RollbackToSavepointClause as RollbackToSavepointClause,
|
||||
)
|
||||
from .sql.expression import SavepointClause as SavepointClause
|
||||
from .sql.expression import ScalarSelect as ScalarSelect
|
||||
from .sql.expression import Select as Select
|
||||
from .sql.expression import select as select
|
||||
from .sql.expression import Selectable as Selectable
|
||||
from .sql.expression import SelectBase as SelectBase
|
||||
from .sql.expression import SQLColumnExpression as SQLColumnExpression
|
||||
from .sql.expression import StatementLambdaElement as StatementLambdaElement
|
||||
from .sql.expression import Subquery as Subquery
|
||||
from .sql.expression import table as table
|
||||
from .sql.expression import TableClause as TableClause
|
||||
from .sql.expression import TableSample as TableSample
|
||||
from .sql.expression import tablesample as tablesample
|
||||
from .sql.expression import TableValuedAlias as TableValuedAlias
|
||||
from .sql.expression import text as text
|
||||
from .sql.expression import TextAsFrom as TextAsFrom
|
||||
from .sql.expression import TextClause as TextClause
|
||||
from .sql.expression import TextualSelect as TextualSelect
|
||||
from .sql.expression import true as true
|
||||
from .sql.expression import True_ as True_
|
||||
from .sql.expression import try_cast as try_cast
|
||||
from .sql.expression import TryCast as TryCast
|
||||
from .sql.expression import Tuple as Tuple
|
||||
from .sql.expression import tuple_ as tuple_
|
||||
from .sql.expression import type_coerce as type_coerce
|
||||
from .sql.expression import TypeClause as TypeClause
|
||||
from .sql.expression import TypeCoerce as TypeCoerce
|
||||
from .sql.expression import UnaryExpression as UnaryExpression
|
||||
from .sql.expression import union as union
|
||||
from .sql.expression import union_all as union_all
|
||||
from .sql.expression import Update as Update
|
||||
from .sql.expression import update as update
|
||||
from .sql.expression import UpdateBase as UpdateBase
|
||||
from .sql.expression import Values as Values
|
||||
from .sql.expression import values as values
|
||||
from .sql.expression import ValuesBase as ValuesBase
|
||||
from .sql.expression import Visitable as Visitable
|
||||
from .sql.expression import within_group as within_group
|
||||
from .sql.expression import WithinGroup as WithinGroup
|
||||
from .types import ARRAY as ARRAY
|
||||
from .types import BIGINT as BIGINT
|
||||
from .types import BigInteger as BigInteger
|
||||
from .types import BINARY as BINARY
|
||||
from .types import BLOB as BLOB
|
||||
from .types import BOOLEAN as BOOLEAN
|
||||
from .types import Boolean as Boolean
|
||||
from .types import CHAR as CHAR
|
||||
from .types import CLOB as CLOB
|
||||
from .types import DATE as DATE
|
||||
from .types import Date as Date
|
||||
from .types import DATETIME as DATETIME
|
||||
from .types import DateTime as DateTime
|
||||
from .types import DECIMAL as DECIMAL
|
||||
from .types import DOUBLE as DOUBLE
|
||||
from .types import Double as Double
|
||||
from .types import DOUBLE_PRECISION as DOUBLE_PRECISION
|
||||
from .types import Enum as Enum
|
||||
from .types import FLOAT as FLOAT
|
||||
from .types import Float as Float
|
||||
from .types import INT as INT
|
||||
from .types import INTEGER as INTEGER
|
||||
from .types import Integer as Integer
|
||||
from .types import Interval as Interval
|
||||
from .types import JSON as JSON
|
||||
from .types import LargeBinary as LargeBinary
|
||||
from .types import NCHAR as NCHAR
|
||||
from .types import NUMERIC as NUMERIC
|
||||
from .types import Numeric as Numeric
|
||||
from .types import NVARCHAR as NVARCHAR
|
||||
from .types import PickleType as PickleType
|
||||
from .types import REAL as REAL
|
||||
from .types import SMALLINT as SMALLINT
|
||||
from .types import SmallInteger as SmallInteger
|
||||
from .types import String as String
|
||||
from .types import TEXT as TEXT
|
||||
from .types import Text as Text
|
||||
from .types import TIME as TIME
|
||||
from .types import Time as Time
|
||||
from .types import TIMESTAMP as TIMESTAMP
|
||||
from .types import TupleType as TupleType
|
||||
from .types import TypeDecorator as TypeDecorator
|
||||
from .types import Unicode as Unicode
|
||||
from .types import UnicodeText as UnicodeText
|
||||
from .types import UUID as UUID
|
||||
from .types import Uuid as Uuid
|
||||
from .types import VARBINARY as VARBINARY
|
||||
from .types import VARCHAR as VARCHAR
|
||||
|
||||
__version__ = "2.0.51"
|
||||
|
||||
|
||||
def __go(lcls: Any) -> None:
|
||||
_util.preloaded.import_prefix("sqlalchemy")
|
||||
|
||||
from . import exc
|
||||
|
||||
exc._version_token = "".join(__version__.split(".")[0:2])
|
||||
|
||||
|
||||
__go(locals())
|
||||
17
venv/Lib/site-packages/sqlalchemy/events.py
Normal file
17
venv/Lib/site-packages/sqlalchemy/events.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# events.py
|
||||
# Copyright (C) 2005-2026 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
|
||||
|
||||
"""Core event interfaces."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .engine.events import ConnectionEvents
|
||||
from .engine.events import DialectEvents
|
||||
from .pool import PoolResetState
|
||||
from .pool.events import PoolEvents
|
||||
from .sql.base import SchemaEventTarget
|
||||
from .sql.events import DDLEvents
|
||||
833
venv/Lib/site-packages/sqlalchemy/exc.py
Normal file
833
venv/Lib/site-packages/sqlalchemy/exc.py
Normal file
@@ -0,0 +1,833 @@
|
||||
# exc.py
|
||||
# Copyright (C) 2005-2026 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
|
||||
|
||||
"""Exceptions used with SQLAlchemy.
|
||||
|
||||
The base exception class is :exc:`.SQLAlchemyError`. Exceptions which are
|
||||
raised as a result of DBAPI exceptions are all subclasses of
|
||||
:exc:`.DBAPIError`.
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import typing
|
||||
from typing import Any
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
from typing import overload
|
||||
from typing import Tuple
|
||||
from typing import Type
|
||||
from typing import Union
|
||||
|
||||
from .util import compat
|
||||
from .util import preloaded as _preloaded
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
from .engine.interfaces import _AnyExecuteParams
|
||||
from .engine.interfaces import Dialect
|
||||
from .sql.compiler import Compiled
|
||||
from .sql.compiler import TypeCompiler
|
||||
from .sql.elements import ClauseElement
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
_version_token: str
|
||||
else:
|
||||
# set by __init__.py
|
||||
_version_token = None
|
||||
|
||||
|
||||
class HasDescriptionCode:
|
||||
"""helper which adds 'code' as an attribute and '_code_str' as a method"""
|
||||
|
||||
code: Optional[str] = None
|
||||
|
||||
def __init__(self, *arg: Any, **kw: Any):
|
||||
code = kw.pop("code", None)
|
||||
if code is not None:
|
||||
self.code = code
|
||||
super().__init__(*arg, **kw)
|
||||
|
||||
_what_are_we = "error"
|
||||
|
||||
def _code_str(self) -> str:
|
||||
if not self.code:
|
||||
return ""
|
||||
else:
|
||||
return (
|
||||
f"(Background on this {self._what_are_we} at: "
|
||||
f"https://sqlalche.me/e/{_version_token}/{self.code})"
|
||||
)
|
||||
|
||||
def __str__(self) -> str:
|
||||
message = super().__str__()
|
||||
if self.code:
|
||||
message = "%s %s" % (message, self._code_str())
|
||||
return message
|
||||
|
||||
|
||||
class SQLAlchemyError(HasDescriptionCode, Exception):
|
||||
"""Generic error class."""
|
||||
|
||||
def _message(self) -> str:
|
||||
# rules:
|
||||
#
|
||||
# 1. single arg string will usually be a unicode
|
||||
# object, but since __str__() must return unicode, check for
|
||||
# bytestring just in case
|
||||
#
|
||||
# 2. for multiple self.args, this is not a case in current
|
||||
# SQLAlchemy though this is happening in at least one known external
|
||||
# library, call str() which does a repr().
|
||||
#
|
||||
text: str
|
||||
|
||||
if len(self.args) == 1:
|
||||
arg_text = self.args[0]
|
||||
|
||||
if isinstance(arg_text, bytes):
|
||||
text = compat.decode_backslashreplace(arg_text, "utf-8")
|
||||
# This is for when the argument is not a string of any sort.
|
||||
# Otherwise, converting this exception to string would fail for
|
||||
# non-string arguments.
|
||||
else:
|
||||
text = str(arg_text)
|
||||
|
||||
return text
|
||||
else:
|
||||
# this is not a normal case within SQLAlchemy but is here for
|
||||
# compatibility with Exception.args - the str() comes out as
|
||||
# a repr() of the tuple
|
||||
return str(self.args)
|
||||
|
||||
def _sql_message(self) -> str:
|
||||
message = self._message()
|
||||
|
||||
if self.code:
|
||||
message = "%s %s" % (message, self._code_str())
|
||||
|
||||
return message
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self._sql_message()
|
||||
|
||||
|
||||
class ArgumentError(SQLAlchemyError):
|
||||
"""Raised when an invalid or conflicting function argument is supplied.
|
||||
|
||||
This error generally corresponds to construction time state errors.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class DuplicateColumnError(ArgumentError):
|
||||
"""a Column is being added to a Table that would replace another
|
||||
Column, without appropriate parameters to allow this in place.
|
||||
|
||||
.. versionadded:: 2.0.0b4
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class ObjectNotExecutableError(ArgumentError):
|
||||
"""Raised when an object is passed to .execute() that can't be
|
||||
executed as SQL.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, target: Any):
|
||||
super().__init__("Not an executable object: %r" % target)
|
||||
self.target = target
|
||||
|
||||
def __reduce__(self) -> Union[str, Tuple[Any, ...]]:
|
||||
return self.__class__, (self.target,)
|
||||
|
||||
|
||||
class NoSuchModuleError(ArgumentError):
|
||||
"""Raised when a dynamically-loaded module (usually a database dialect)
|
||||
of a particular name cannot be located."""
|
||||
|
||||
|
||||
class NoForeignKeysError(ArgumentError):
|
||||
"""Raised when no foreign keys can be located between two selectables
|
||||
during a join."""
|
||||
|
||||
|
||||
class AmbiguousForeignKeysError(ArgumentError):
|
||||
"""Raised when more than one foreign key matching can be located
|
||||
between two selectables during a join."""
|
||||
|
||||
|
||||
class ConstraintColumnNotFoundError(ArgumentError):
|
||||
"""raised when a constraint refers to a string column name that
|
||||
is not present in the table being constrained.
|
||||
|
||||
.. versionadded:: 2.0
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class CircularDependencyError(SQLAlchemyError):
|
||||
"""Raised by topological sorts when a circular dependency is detected.
|
||||
|
||||
There are two scenarios where this error occurs:
|
||||
|
||||
* In a Session flush operation, if two objects are mutually dependent
|
||||
on each other, they can not be inserted or deleted via INSERT or
|
||||
DELETE statements alone; an UPDATE will be needed to post-associate
|
||||
or pre-deassociate one of the foreign key constrained values.
|
||||
The ``post_update`` flag described at :ref:`post_update` can resolve
|
||||
this cycle.
|
||||
* In a :attr:`_schema.MetaData.sorted_tables` operation, two
|
||||
:class:`_schema.ForeignKey`
|
||||
or :class:`_schema.ForeignKeyConstraint` objects mutually refer to each
|
||||
other. Apply the ``use_alter=True`` flag to one or both,
|
||||
see :ref:`use_alter`.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
message: str,
|
||||
cycles: Any,
|
||||
edges: Any,
|
||||
msg: Optional[str] = None,
|
||||
code: Optional[str] = None,
|
||||
):
|
||||
if msg is None:
|
||||
message += " (%s)" % ", ".join(repr(s) for s in cycles)
|
||||
else:
|
||||
message = msg
|
||||
SQLAlchemyError.__init__(self, message, code=code)
|
||||
self.cycles = cycles
|
||||
self.edges = edges
|
||||
|
||||
def __reduce__(self) -> Union[str, Tuple[Any, ...]]:
|
||||
return (
|
||||
self.__class__,
|
||||
(None, self.cycles, self.edges, self.args[0]),
|
||||
{"code": self.code} if self.code is not None else {},
|
||||
)
|
||||
|
||||
|
||||
class CompileError(SQLAlchemyError):
|
||||
"""Raised when an error occurs during SQL compilation"""
|
||||
|
||||
|
||||
class UnsupportedCompilationError(CompileError):
|
||||
"""Raised when an operation is not supported by the given compiler.
|
||||
|
||||
.. seealso::
|
||||
|
||||
:ref:`faq_sql_expression_string`
|
||||
|
||||
:ref:`error_l7de`
|
||||
"""
|
||||
|
||||
code = "l7de"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
compiler: Union[Compiled, TypeCompiler],
|
||||
element_type: Type[ClauseElement],
|
||||
message: Optional[str] = None,
|
||||
):
|
||||
super().__init__(
|
||||
"Compiler %r can't render element of type %s%s"
|
||||
% (compiler, element_type, ": %s" % message if message else "")
|
||||
)
|
||||
self.compiler = compiler
|
||||
self.element_type = element_type
|
||||
self.message = message
|
||||
|
||||
def __reduce__(self) -> Union[str, Tuple[Any, ...]]:
|
||||
return self.__class__, (self.compiler, self.element_type, self.message)
|
||||
|
||||
|
||||
class IdentifierError(SQLAlchemyError):
|
||||
"""Raised when a schema name is beyond the max character limit"""
|
||||
|
||||
|
||||
class DisconnectionError(SQLAlchemyError):
|
||||
"""A disconnect is detected on a raw DB-API connection.
|
||||
|
||||
This error is raised and consumed internally by a connection pool. It can
|
||||
be raised by the :meth:`_events.PoolEvents.checkout`
|
||||
event so that the host pool
|
||||
forces a retry; the exception will be caught three times in a row before
|
||||
the pool gives up and raises :class:`~sqlalchemy.exc.InvalidRequestError`
|
||||
regarding the connection attempt.
|
||||
|
||||
"""
|
||||
|
||||
invalidate_pool: bool = False
|
||||
|
||||
|
||||
class InvalidatePoolError(DisconnectionError):
|
||||
"""Raised when the connection pool should invalidate all stale connections.
|
||||
|
||||
A subclass of :class:`_exc.DisconnectionError` that indicates that the
|
||||
disconnect situation encountered on the connection probably means the
|
||||
entire pool should be invalidated, as the database has been restarted.
|
||||
|
||||
This exception will be handled otherwise the same way as
|
||||
:class:`_exc.DisconnectionError`, allowing three attempts to reconnect
|
||||
before giving up.
|
||||
|
||||
.. versionadded:: 1.2
|
||||
|
||||
"""
|
||||
|
||||
invalidate_pool: bool = True
|
||||
|
||||
|
||||
class TimeoutError(SQLAlchemyError): # noqa
|
||||
"""Raised when a connection pool times out on getting a connection."""
|
||||
|
||||
|
||||
class InvalidRequestError(SQLAlchemyError):
|
||||
"""SQLAlchemy was asked to do something it can't do.
|
||||
|
||||
This error generally corresponds to runtime state errors.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class IllegalStateChangeError(InvalidRequestError):
|
||||
"""An object that tracks state encountered an illegal state change
|
||||
of some kind.
|
||||
|
||||
.. versionadded:: 2.0
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class NoInspectionAvailable(InvalidRequestError):
|
||||
"""A subject passed to :func:`sqlalchemy.inspection.inspect` produced
|
||||
no context for inspection."""
|
||||
|
||||
|
||||
class PendingRollbackError(InvalidRequestError):
|
||||
"""A transaction has failed and needs to be rolled back before
|
||||
continuing.
|
||||
|
||||
.. versionadded:: 1.4
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class ResourceClosedError(InvalidRequestError):
|
||||
"""An operation was requested from a connection, cursor, or other
|
||||
object that's in a closed state."""
|
||||
|
||||
|
||||
class NoSuchColumnError(InvalidRequestError, KeyError):
|
||||
"""A nonexistent column is requested from a ``Row``."""
|
||||
|
||||
|
||||
class NoResultFound(InvalidRequestError):
|
||||
"""A database result was required but none was found.
|
||||
|
||||
|
||||
.. versionchanged:: 1.4 This exception is now part of the
|
||||
``sqlalchemy.exc`` module in Core, moved from the ORM. The symbol
|
||||
remains importable from ``sqlalchemy.orm.exc``.
|
||||
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class MultipleResultsFound(InvalidRequestError):
|
||||
"""A single database result was required but more than one were found.
|
||||
|
||||
.. versionchanged:: 1.4 This exception is now part of the
|
||||
``sqlalchemy.exc`` module in Core, moved from the ORM. The symbol
|
||||
remains importable from ``sqlalchemy.orm.exc``.
|
||||
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class NoReferenceError(InvalidRequestError):
|
||||
"""Raised by ``ForeignKey`` to indicate a reference cannot be resolved."""
|
||||
|
||||
table_name: str
|
||||
|
||||
|
||||
class AwaitRequired(InvalidRequestError):
|
||||
"""Error raised by the async greenlet spawn if no async operation
|
||||
was awaited when it required one.
|
||||
|
||||
"""
|
||||
|
||||
code = "xd1r"
|
||||
|
||||
|
||||
class MissingGreenlet(InvalidRequestError):
|
||||
r"""Error raised by the async greenlet await\_ if called while not inside
|
||||
the greenlet spawn context.
|
||||
|
||||
"""
|
||||
|
||||
code = "xd2s"
|
||||
|
||||
|
||||
class NoReferencedTableError(NoReferenceError):
|
||||
"""Raised by ``ForeignKey`` when the referred ``Table`` cannot be
|
||||
located.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, message: str, tname: str):
|
||||
NoReferenceError.__init__(self, message)
|
||||
self.table_name = tname
|
||||
|
||||
def __reduce__(self) -> Union[str, Tuple[Any, ...]]:
|
||||
return self.__class__, (self.args[0], self.table_name)
|
||||
|
||||
|
||||
class NoReferencedColumnError(NoReferenceError):
|
||||
"""Raised by ``ForeignKey`` when the referred ``Column`` cannot be
|
||||
located.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, message: str, tname: str, cname: str):
|
||||
NoReferenceError.__init__(self, message)
|
||||
self.table_name = tname
|
||||
self.column_name = cname
|
||||
|
||||
def __reduce__(self) -> Union[str, Tuple[Any, ...]]:
|
||||
return (
|
||||
self.__class__,
|
||||
(self.args[0], self.table_name, self.column_name),
|
||||
)
|
||||
|
||||
|
||||
class NoSuchTableError(InvalidRequestError):
|
||||
"""Table does not exist or is not visible to a connection."""
|
||||
|
||||
|
||||
class UnreflectableTableError(InvalidRequestError):
|
||||
"""Table exists but can't be reflected for some reason.
|
||||
|
||||
.. versionadded:: 1.2
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class UnboundExecutionError(InvalidRequestError):
|
||||
"""SQL was attempted without a database connection to execute it on."""
|
||||
|
||||
|
||||
class DontWrapMixin:
|
||||
"""A mixin class which, when applied to a user-defined Exception class,
|
||||
will not be wrapped inside of :exc:`.StatementError` if the error is
|
||||
emitted within the process of executing a statement.
|
||||
|
||||
E.g.::
|
||||
|
||||
from sqlalchemy.exc import DontWrapMixin
|
||||
|
||||
|
||||
class MyCustomException(Exception, DontWrapMixin):
|
||||
pass
|
||||
|
||||
|
||||
class MySpecialType(TypeDecorator):
|
||||
impl = String
|
||||
|
||||
def process_bind_param(self, value, dialect):
|
||||
if value == "invalid":
|
||||
raise MyCustomException("invalid!")
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class StatementError(SQLAlchemyError):
|
||||
"""An error occurred during execution of a SQL statement.
|
||||
|
||||
:class:`StatementError` wraps the exception raised
|
||||
during execution, and features :attr:`.statement`
|
||||
and :attr:`.params` attributes which supply context regarding
|
||||
the specifics of the statement which had an issue.
|
||||
|
||||
The wrapped exception object is available in
|
||||
the :attr:`.orig` attribute.
|
||||
|
||||
"""
|
||||
|
||||
statement: Optional[str] = None
|
||||
"""The string SQL statement being invoked when this exception occurred."""
|
||||
|
||||
params: Optional[_AnyExecuteParams] = None
|
||||
"""The parameter list being used when this exception occurred."""
|
||||
|
||||
orig: Optional[BaseException] = None
|
||||
"""The original exception that was thrown.
|
||||
|
||||
"""
|
||||
|
||||
ismulti: Optional[bool] = None
|
||||
"""multi parameter passed to repr_params(). None is meaningful."""
|
||||
|
||||
connection_invalidated: bool = False
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
message: str,
|
||||
statement: Optional[str],
|
||||
params: Optional[_AnyExecuteParams],
|
||||
orig: Optional[BaseException],
|
||||
hide_parameters: bool = False,
|
||||
code: Optional[str] = None,
|
||||
ismulti: Optional[bool] = None,
|
||||
):
|
||||
SQLAlchemyError.__init__(self, message, code=code)
|
||||
self.statement = statement
|
||||
self.params = params
|
||||
self.orig = orig
|
||||
self.ismulti = ismulti
|
||||
self.hide_parameters = hide_parameters
|
||||
self.detail: List[str] = []
|
||||
|
||||
def add_detail(self, msg: str) -> None:
|
||||
self.detail.append(msg)
|
||||
|
||||
def __reduce__(self) -> Union[str, Tuple[Any, ...]]:
|
||||
return (
|
||||
self.__class__,
|
||||
(
|
||||
self.args[0],
|
||||
self.statement,
|
||||
self.params,
|
||||
self.orig,
|
||||
self.hide_parameters,
|
||||
self.__dict__.get("code"),
|
||||
self.ismulti,
|
||||
),
|
||||
{"detail": self.detail},
|
||||
)
|
||||
|
||||
@_preloaded.preload_module("sqlalchemy.sql.util")
|
||||
def _sql_message(self) -> str:
|
||||
util = _preloaded.sql_util
|
||||
|
||||
details = [self._message()]
|
||||
if self.statement:
|
||||
stmt_detail = "[SQL: %s]" % self.statement
|
||||
details.append(stmt_detail)
|
||||
if self.params:
|
||||
if self.hide_parameters:
|
||||
details.append(
|
||||
"[SQL parameters hidden due to hide_parameters=True]"
|
||||
)
|
||||
else:
|
||||
params_repr = util._repr_params(
|
||||
self.params, 10, ismulti=self.ismulti
|
||||
)
|
||||
details.append("[parameters: %r]" % params_repr)
|
||||
code_str = self._code_str()
|
||||
if code_str:
|
||||
details.append(code_str)
|
||||
return "\n".join(["(%s)" % det for det in self.detail] + details)
|
||||
|
||||
|
||||
class DBAPIError(StatementError):
|
||||
"""Raised when the execution of a database operation fails.
|
||||
|
||||
Wraps exceptions raised by the DB-API underlying the
|
||||
database operation. Driver-specific implementations of the standard
|
||||
DB-API exception types are wrapped by matching sub-types of SQLAlchemy's
|
||||
:class:`DBAPIError` when possible. DB-API's ``Error`` type maps to
|
||||
:class:`DBAPIError` in SQLAlchemy, otherwise the names are identical. Note
|
||||
that there is no guarantee that different DB-API implementations will
|
||||
raise the same exception type for any given error condition.
|
||||
|
||||
:class:`DBAPIError` features :attr:`~.StatementError.statement`
|
||||
and :attr:`~.StatementError.params` attributes which supply context
|
||||
regarding the specifics of the statement which had an issue, for the
|
||||
typical case when the error was raised within the context of
|
||||
emitting a SQL statement.
|
||||
|
||||
The wrapped exception object is available in the
|
||||
:attr:`~.StatementError.orig` attribute. Its type and properties are
|
||||
DB-API implementation specific.
|
||||
|
||||
"""
|
||||
|
||||
code = "dbapi"
|
||||
|
||||
@overload
|
||||
@classmethod
|
||||
def instance(
|
||||
cls,
|
||||
statement: Optional[str],
|
||||
params: Optional[_AnyExecuteParams],
|
||||
orig: Exception,
|
||||
dbapi_base_err: Type[Exception],
|
||||
hide_parameters: bool = False,
|
||||
connection_invalidated: bool = False,
|
||||
dialect: Optional[Dialect] = None,
|
||||
ismulti: Optional[bool] = None,
|
||||
) -> StatementError: ...
|
||||
|
||||
@overload
|
||||
@classmethod
|
||||
def instance(
|
||||
cls,
|
||||
statement: Optional[str],
|
||||
params: Optional[_AnyExecuteParams],
|
||||
orig: DontWrapMixin,
|
||||
dbapi_base_err: Type[Exception],
|
||||
hide_parameters: bool = False,
|
||||
connection_invalidated: bool = False,
|
||||
dialect: Optional[Dialect] = None,
|
||||
ismulti: Optional[bool] = None,
|
||||
) -> DontWrapMixin: ...
|
||||
|
||||
@overload
|
||||
@classmethod
|
||||
def instance(
|
||||
cls,
|
||||
statement: Optional[str],
|
||||
params: Optional[_AnyExecuteParams],
|
||||
orig: BaseException,
|
||||
dbapi_base_err: Type[Exception],
|
||||
hide_parameters: bool = False,
|
||||
connection_invalidated: bool = False,
|
||||
dialect: Optional[Dialect] = None,
|
||||
ismulti: Optional[bool] = None,
|
||||
) -> BaseException: ...
|
||||
|
||||
@classmethod
|
||||
def instance(
|
||||
cls,
|
||||
statement: Optional[str],
|
||||
params: Optional[_AnyExecuteParams],
|
||||
orig: Union[BaseException, DontWrapMixin],
|
||||
dbapi_base_err: Type[Exception],
|
||||
hide_parameters: bool = False,
|
||||
connection_invalidated: bool = False,
|
||||
dialect: Optional[Dialect] = None,
|
||||
ismulti: Optional[bool] = None,
|
||||
) -> Union[BaseException, DontWrapMixin]:
|
||||
# Don't ever wrap these, just return them directly as if
|
||||
# DBAPIError didn't exist.
|
||||
if (
|
||||
isinstance(orig, BaseException) and not isinstance(orig, Exception)
|
||||
) or isinstance(orig, DontWrapMixin):
|
||||
return orig
|
||||
|
||||
if orig is not None:
|
||||
# not a DBAPI error, statement is present.
|
||||
# raise a StatementError
|
||||
if isinstance(orig, SQLAlchemyError) and statement:
|
||||
return StatementError(
|
||||
"(%s.%s) %s"
|
||||
% (
|
||||
orig.__class__.__module__,
|
||||
orig.__class__.__name__,
|
||||
orig.args[0],
|
||||
),
|
||||
statement,
|
||||
params,
|
||||
orig,
|
||||
hide_parameters=hide_parameters,
|
||||
code=orig.code,
|
||||
ismulti=ismulti,
|
||||
)
|
||||
elif not isinstance(orig, dbapi_base_err) and statement:
|
||||
return StatementError(
|
||||
"(%s.%s) %s"
|
||||
% (
|
||||
orig.__class__.__module__,
|
||||
orig.__class__.__name__,
|
||||
orig,
|
||||
),
|
||||
statement,
|
||||
params,
|
||||
orig,
|
||||
hide_parameters=hide_parameters,
|
||||
ismulti=ismulti,
|
||||
)
|
||||
|
||||
glob = globals()
|
||||
for super_ in orig.__class__.__mro__:
|
||||
name = super_.__name__
|
||||
if dialect:
|
||||
name = dialect.dbapi_exception_translation_map.get(
|
||||
name, name
|
||||
)
|
||||
if name in glob and issubclass(glob[name], DBAPIError):
|
||||
cls = glob[name]
|
||||
break
|
||||
|
||||
return cls(
|
||||
statement,
|
||||
params,
|
||||
orig,
|
||||
connection_invalidated=connection_invalidated,
|
||||
hide_parameters=hide_parameters,
|
||||
code=cls.code,
|
||||
ismulti=ismulti,
|
||||
)
|
||||
|
||||
def __reduce__(self) -> Union[str, Tuple[Any, ...]]:
|
||||
return (
|
||||
self.__class__,
|
||||
(
|
||||
self.statement,
|
||||
self.params,
|
||||
self.orig,
|
||||
self.hide_parameters,
|
||||
self.connection_invalidated,
|
||||
self.__dict__.get("code"),
|
||||
self.ismulti,
|
||||
),
|
||||
{"detail": self.detail},
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
statement: Optional[str],
|
||||
params: Optional[_AnyExecuteParams],
|
||||
orig: BaseException,
|
||||
hide_parameters: bool = False,
|
||||
connection_invalidated: bool = False,
|
||||
code: Optional[str] = None,
|
||||
ismulti: Optional[bool] = None,
|
||||
):
|
||||
try:
|
||||
text = str(orig)
|
||||
except Exception as e:
|
||||
text = "Error in str() of DB-API-generated exception: " + str(e)
|
||||
StatementError.__init__(
|
||||
self,
|
||||
"(%s.%s) %s"
|
||||
% (orig.__class__.__module__, orig.__class__.__name__, text),
|
||||
statement,
|
||||
params,
|
||||
orig,
|
||||
hide_parameters,
|
||||
code=code,
|
||||
ismulti=ismulti,
|
||||
)
|
||||
self.connection_invalidated = connection_invalidated
|
||||
|
||||
|
||||
class InterfaceError(DBAPIError):
|
||||
"""Wraps a DB-API InterfaceError."""
|
||||
|
||||
code = "rvf5"
|
||||
|
||||
|
||||
class DatabaseError(DBAPIError):
|
||||
"""Wraps a DB-API DatabaseError."""
|
||||
|
||||
code = "4xp6"
|
||||
|
||||
|
||||
class DataError(DatabaseError):
|
||||
"""Wraps a DB-API DataError."""
|
||||
|
||||
code = "9h9h"
|
||||
|
||||
|
||||
class OperationalError(DatabaseError):
|
||||
"""Wraps a DB-API OperationalError."""
|
||||
|
||||
code = "e3q8"
|
||||
|
||||
|
||||
class IntegrityError(DatabaseError):
|
||||
"""Wraps a DB-API IntegrityError."""
|
||||
|
||||
code = "gkpj"
|
||||
|
||||
|
||||
class InternalError(DatabaseError):
|
||||
"""Wraps a DB-API InternalError."""
|
||||
|
||||
code = "2j85"
|
||||
|
||||
|
||||
class ProgrammingError(DatabaseError):
|
||||
"""Wraps a DB-API ProgrammingError."""
|
||||
|
||||
code = "f405"
|
||||
|
||||
|
||||
class NotSupportedError(DatabaseError):
|
||||
"""Wraps a DB-API NotSupportedError."""
|
||||
|
||||
code = "tw8g"
|
||||
|
||||
|
||||
# Warnings
|
||||
|
||||
|
||||
class SATestSuiteWarning(Warning):
|
||||
"""warning for a condition detected during tests that is non-fatal
|
||||
|
||||
Currently outside of SAWarning so that we can work around tools like
|
||||
Alembic doing the wrong thing with warnings.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class SADeprecationWarning(HasDescriptionCode, DeprecationWarning):
|
||||
"""Issued for usage of deprecated APIs."""
|
||||
|
||||
deprecated_since: Optional[str] = None
|
||||
"Indicates the version that started raising this deprecation warning"
|
||||
|
||||
|
||||
class Base20DeprecationWarning(SADeprecationWarning):
|
||||
"""Issued for usage of APIs specifically deprecated or legacy in
|
||||
SQLAlchemy 2.0.
|
||||
|
||||
.. seealso::
|
||||
|
||||
:ref:`error_b8d9`.
|
||||
|
||||
:ref:`deprecation_20_mode`
|
||||
|
||||
"""
|
||||
|
||||
deprecated_since: Optional[str] = "1.4"
|
||||
"Indicates the version that started raising this deprecation warning"
|
||||
|
||||
def __str__(self) -> str:
|
||||
return (
|
||||
super().__str__()
|
||||
+ " (Background on SQLAlchemy 2.0 at: https://sqlalche.me/e/b8d9)"
|
||||
)
|
||||
|
||||
|
||||
class LegacyAPIWarning(Base20DeprecationWarning):
|
||||
"""indicates an API that is in 'legacy' status, a long term deprecation."""
|
||||
|
||||
|
||||
class MovedIn20Warning(Base20DeprecationWarning):
|
||||
"""Subtype of RemovedIn20Warning to indicate an API that moved only."""
|
||||
|
||||
|
||||
class SAPendingDeprecationWarning(PendingDeprecationWarning):
|
||||
"""A similar warning as :class:`_exc.SADeprecationWarning`, this warning
|
||||
is not used in modern versions of SQLAlchemy.
|
||||
|
||||
"""
|
||||
|
||||
deprecated_since: Optional[str] = None
|
||||
"Indicates the version that started raising this deprecation warning"
|
||||
|
||||
|
||||
class SAWarning(HasDescriptionCode, RuntimeWarning):
|
||||
"""Issued at runtime."""
|
||||
|
||||
_what_are_we = "warning"
|
||||
175
venv/Lib/site-packages/sqlalchemy/inspection.py
Normal file
175
venv/Lib/site-packages/sqlalchemy/inspection.py
Normal file
@@ -0,0 +1,175 @@
|
||||
# inspection.py
|
||||
# Copyright (C) 2005-2026 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
|
||||
|
||||
"""The inspection module provides the :func:`_sa.inspect` function,
|
||||
which delivers runtime information about a wide variety
|
||||
of SQLAlchemy objects, both within the Core as well as the
|
||||
ORM.
|
||||
|
||||
The :func:`_sa.inspect` function is the entry point to SQLAlchemy's
|
||||
public API for viewing the configuration and construction
|
||||
of in-memory objects. Depending on the type of object
|
||||
passed to :func:`_sa.inspect`, the return value will either be
|
||||
a related object which provides a known interface, or in many
|
||||
cases it will return the object itself.
|
||||
|
||||
The rationale for :func:`_sa.inspect` is twofold. One is that
|
||||
it replaces the need to be aware of a large variety of "information
|
||||
getting" functions in SQLAlchemy, such as
|
||||
:meth:`_reflection.Inspector.from_engine` (deprecated in 1.4),
|
||||
:func:`.orm.attributes.instance_state`, :func:`_orm.class_mapper`,
|
||||
and others. The other is that the return value of :func:`_sa.inspect`
|
||||
is guaranteed to obey a documented API, thus allowing third party
|
||||
tools which build on top of SQLAlchemy configurations to be constructed
|
||||
in a forwards-compatible way.
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
from typing import Callable
|
||||
from typing import Dict
|
||||
from typing import Generic
|
||||
from typing import Optional
|
||||
from typing import overload
|
||||
from typing import Type
|
||||
from typing import TypeVar
|
||||
from typing import Union
|
||||
|
||||
from . import exc
|
||||
from .util.typing import Literal
|
||||
from .util.typing import Protocol
|
||||
|
||||
_T = TypeVar("_T", bound=Any)
|
||||
_TCov = TypeVar("_TCov", bound=Any, covariant=True)
|
||||
_F = TypeVar("_F", bound=Callable[..., Any])
|
||||
|
||||
_IN = TypeVar("_IN", bound=Any)
|
||||
|
||||
_registrars: Dict[type, Union[Literal[True], Callable[[Any], Any]]] = {}
|
||||
|
||||
|
||||
class Inspectable(Generic[_T]):
|
||||
"""define a class as inspectable.
|
||||
|
||||
This allows typing to set up a linkage between an object that
|
||||
can be inspected and the type of inspection it returns.
|
||||
|
||||
Unfortunately we cannot at the moment get all classes that are
|
||||
returned by inspection to suit this interface as we get into
|
||||
MRO issues.
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
|
||||
class _InspectableTypeProtocol(Protocol[_TCov]):
|
||||
"""a protocol defining a method that's used when a type (ie the class
|
||||
itself) is passed to inspect().
|
||||
|
||||
"""
|
||||
|
||||
def _sa_inspect_type(self) -> _TCov: ...
|
||||
|
||||
|
||||
class _InspectableProtocol(Protocol[_TCov]):
|
||||
"""a protocol defining a method that's used when an instance is
|
||||
passed to inspect().
|
||||
|
||||
"""
|
||||
|
||||
def _sa_inspect_instance(self) -> _TCov: ...
|
||||
|
||||
|
||||
@overload
|
||||
def inspect(
|
||||
subject: Type[_InspectableTypeProtocol[_IN]], raiseerr: bool = True
|
||||
) -> _IN: ...
|
||||
|
||||
|
||||
@overload
|
||||
def inspect(
|
||||
subject: _InspectableProtocol[_IN], raiseerr: bool = True
|
||||
) -> _IN: ...
|
||||
|
||||
|
||||
@overload
|
||||
def inspect(subject: Inspectable[_IN], raiseerr: bool = True) -> _IN: ...
|
||||
|
||||
|
||||
@overload
|
||||
def inspect(subject: Any, raiseerr: Literal[False] = ...) -> Optional[Any]: ...
|
||||
|
||||
|
||||
@overload
|
||||
def inspect(subject: Any, raiseerr: bool = True) -> Any: ...
|
||||
|
||||
|
||||
def inspect(subject: Any, raiseerr: bool = True) -> Any:
|
||||
"""Produce an inspection object for the given target.
|
||||
|
||||
The returned value in some cases may be the
|
||||
same object as the one given, such as if a
|
||||
:class:`_orm.Mapper` object is passed. In other
|
||||
cases, it will be an instance of the registered
|
||||
inspection type for the given object, such as
|
||||
if an :class:`_engine.Engine` is passed, an
|
||||
:class:`_reflection.Inspector` object is returned.
|
||||
|
||||
:param subject: the subject to be inspected.
|
||||
:param raiseerr: When ``True``, if the given subject
|
||||
does not
|
||||
correspond to a known SQLAlchemy inspected type,
|
||||
:class:`sqlalchemy.exc.NoInspectionAvailable`
|
||||
is raised. If ``False``, ``None`` is returned.
|
||||
|
||||
"""
|
||||
type_ = type(subject)
|
||||
for cls in type_.__mro__:
|
||||
if cls in _registrars:
|
||||
reg = _registrars.get(cls, None)
|
||||
if reg is None:
|
||||
continue
|
||||
elif reg is True:
|
||||
return subject
|
||||
ret = reg(subject)
|
||||
if ret is not None:
|
||||
return ret
|
||||
else:
|
||||
reg = ret = None
|
||||
|
||||
if raiseerr and (reg is None or ret is None):
|
||||
raise exc.NoInspectionAvailable(
|
||||
"No inspection system is "
|
||||
"available for object of type %s" % type_
|
||||
)
|
||||
return ret
|
||||
|
||||
|
||||
def _inspects(
|
||||
*types: Type[Any],
|
||||
) -> Callable[[_F], _F]:
|
||||
def decorate(fn_or_cls: _F) -> _F:
|
||||
for type_ in types:
|
||||
if type_ in _registrars:
|
||||
raise AssertionError("Type %s is already registered" % type_)
|
||||
_registrars[type_] = fn_or_cls
|
||||
return fn_or_cls
|
||||
|
||||
return decorate
|
||||
|
||||
|
||||
_TT = TypeVar("_TT", bound="Type[Any]")
|
||||
|
||||
|
||||
def _self_inspects(cls: _TT) -> _TT:
|
||||
if cls in _registrars:
|
||||
raise AssertionError("Type %s is already registered" % cls)
|
||||
_registrars[cls] = True
|
||||
return cls
|
||||
288
venv/Lib/site-packages/sqlalchemy/log.py
Normal file
288
venv/Lib/site-packages/sqlalchemy/log.py
Normal file
@@ -0,0 +1,288 @@
|
||||
# log.py
|
||||
# Copyright (C) 2006-2026 the SQLAlchemy authors and contributors
|
||||
# <see AUTHORS file>
|
||||
# Includes alterations by Vinay Sajip vinay_sajip@yahoo.co.uk
|
||||
#
|
||||
# This module is part of SQLAlchemy and is released under
|
||||
# the MIT License: https://www.opensource.org/licenses/mit-license.php
|
||||
|
||||
"""Logging control and utilities.
|
||||
|
||||
Control of logging for SA can be performed from the regular python logging
|
||||
module. The regular dotted module namespace is used, starting at
|
||||
'sqlalchemy'. For class-level logging, the class name is appended.
|
||||
|
||||
The "echo" keyword parameter, available on SQLA :class:`_engine.Engine`
|
||||
and :class:`_pool.Pool` objects, corresponds to a logger specific to that
|
||||
instance only.
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import sys
|
||||
from typing import Any
|
||||
from typing import Optional
|
||||
from typing import overload
|
||||
from typing import Set
|
||||
from typing import Type
|
||||
from typing import TypeVar
|
||||
from typing import Union
|
||||
|
||||
from .util import py311
|
||||
from .util import py38
|
||||
from .util.typing import Literal
|
||||
|
||||
if py38:
|
||||
STACKLEVEL = True
|
||||
# needed as of py3.11.0b1
|
||||
# #8019
|
||||
STACKLEVEL_OFFSET = 2 if py311 else 1
|
||||
else:
|
||||
STACKLEVEL = False
|
||||
STACKLEVEL_OFFSET = 0
|
||||
|
||||
_IT = TypeVar("_IT", bound="Identified")
|
||||
|
||||
_EchoFlagType = Union[None, bool, Literal["debug"]]
|
||||
|
||||
# set initial level to WARN. This so that
|
||||
# log statements don't occur in the absence of explicit
|
||||
# logging being enabled for 'sqlalchemy'.
|
||||
rootlogger = logging.getLogger("sqlalchemy")
|
||||
if rootlogger.level == logging.NOTSET:
|
||||
rootlogger.setLevel(logging.WARNING)
|
||||
|
||||
|
||||
def _add_default_handler(logger: logging.Logger) -> None:
|
||||
handler = logging.StreamHandler(sys.stdout)
|
||||
handler.setFormatter(
|
||||
logging.Formatter("%(asctime)s %(levelname)s %(name)s %(message)s")
|
||||
)
|
||||
logger.addHandler(handler)
|
||||
|
||||
|
||||
_logged_classes: Set[Type[Identified]] = set()
|
||||
|
||||
|
||||
def _qual_logger_name_for_cls(cls: Type[Identified]) -> str:
|
||||
return (
|
||||
getattr(cls, "_sqla_logger_namespace", None)
|
||||
or cls.__module__ + "." + cls.__name__
|
||||
)
|
||||
|
||||
|
||||
def class_logger(cls: Type[_IT]) -> Type[_IT]:
|
||||
logger = logging.getLogger(_qual_logger_name_for_cls(cls))
|
||||
cls._should_log_debug = lambda self: logger.isEnabledFor( # type: ignore[method-assign] # noqa: E501
|
||||
logging.DEBUG
|
||||
)
|
||||
cls._should_log_info = lambda self: logger.isEnabledFor( # type: ignore[method-assign] # noqa: E501
|
||||
logging.INFO
|
||||
)
|
||||
cls.logger = logger
|
||||
_logged_classes.add(cls)
|
||||
return cls
|
||||
|
||||
|
||||
_IdentifiedLoggerType = Union[logging.Logger, "InstanceLogger"]
|
||||
|
||||
|
||||
class Identified:
|
||||
__slots__ = ()
|
||||
|
||||
logging_name: Optional[str] = None
|
||||
|
||||
logger: _IdentifiedLoggerType
|
||||
|
||||
_echo: _EchoFlagType
|
||||
|
||||
def _should_log_debug(self) -> bool:
|
||||
return self.logger.isEnabledFor(logging.DEBUG)
|
||||
|
||||
def _should_log_info(self) -> bool:
|
||||
return self.logger.isEnabledFor(logging.INFO)
|
||||
|
||||
|
||||
class InstanceLogger:
|
||||
"""A logger adapter (wrapper) for :class:`.Identified` subclasses.
|
||||
|
||||
This allows multiple instances (e.g. Engine or Pool instances)
|
||||
to share a logger, but have its verbosity controlled on a
|
||||
per-instance basis.
|
||||
|
||||
The basic functionality is to return a logging level
|
||||
which is based on an instance's echo setting.
|
||||
|
||||
Default implementation is:
|
||||
|
||||
'debug' -> logging.DEBUG
|
||||
True -> logging.INFO
|
||||
False -> Effective level of underlying logger (
|
||||
logging.WARNING by default)
|
||||
None -> same as False
|
||||
"""
|
||||
|
||||
# Map echo settings to logger levels
|
||||
_echo_map = {
|
||||
None: logging.NOTSET,
|
||||
False: logging.NOTSET,
|
||||
True: logging.INFO,
|
||||
"debug": logging.DEBUG,
|
||||
}
|
||||
|
||||
_echo: _EchoFlagType
|
||||
|
||||
__slots__ = ("echo", "logger")
|
||||
|
||||
def __init__(self, echo: _EchoFlagType, name: str):
|
||||
self.echo = echo
|
||||
self.logger = logging.getLogger(name)
|
||||
|
||||
# if echo flag is enabled and no handlers,
|
||||
# add a handler to the list
|
||||
if self._echo_map[echo] <= logging.INFO and not self.logger.handlers:
|
||||
_add_default_handler(self.logger)
|
||||
|
||||
#
|
||||
# Boilerplate convenience methods
|
||||
#
|
||||
def debug(self, msg: str, *args: Any, **kwargs: Any) -> None:
|
||||
"""Delegate a debug call to the underlying logger."""
|
||||
|
||||
self.log(logging.DEBUG, msg, *args, **kwargs)
|
||||
|
||||
def info(self, msg: str, *args: Any, **kwargs: Any) -> None:
|
||||
"""Delegate an info call to the underlying logger."""
|
||||
|
||||
self.log(logging.INFO, msg, *args, **kwargs)
|
||||
|
||||
def warning(self, msg: str, *args: Any, **kwargs: Any) -> None:
|
||||
"""Delegate a warning call to the underlying logger."""
|
||||
|
||||
self.log(logging.WARNING, msg, *args, **kwargs)
|
||||
|
||||
warn = warning
|
||||
|
||||
def error(self, msg: str, *args: Any, **kwargs: Any) -> None:
|
||||
"""
|
||||
Delegate an error call to the underlying logger.
|
||||
"""
|
||||
self.log(logging.ERROR, msg, *args, **kwargs)
|
||||
|
||||
def exception(self, msg: str, *args: Any, **kwargs: Any) -> None:
|
||||
"""Delegate an exception call to the underlying logger."""
|
||||
|
||||
kwargs["exc_info"] = 1
|
||||
self.log(logging.ERROR, msg, *args, **kwargs)
|
||||
|
||||
def critical(self, msg: str, *args: Any, **kwargs: Any) -> None:
|
||||
"""Delegate a critical call to the underlying logger."""
|
||||
|
||||
self.log(logging.CRITICAL, msg, *args, **kwargs)
|
||||
|
||||
def log(self, level: int, msg: str, *args: Any, **kwargs: Any) -> None:
|
||||
"""Delegate a log call to the underlying logger.
|
||||
|
||||
The level here is determined by the echo
|
||||
flag as well as that of the underlying logger, and
|
||||
logger._log() is called directly.
|
||||
|
||||
"""
|
||||
|
||||
# inline the logic from isEnabledFor(),
|
||||
# getEffectiveLevel(), to avoid overhead.
|
||||
|
||||
if self.logger.manager.disable >= level:
|
||||
return
|
||||
|
||||
selected_level = self._echo_map[self.echo]
|
||||
if selected_level == logging.NOTSET:
|
||||
selected_level = self.logger.getEffectiveLevel()
|
||||
|
||||
if level >= selected_level:
|
||||
if STACKLEVEL:
|
||||
kwargs["stacklevel"] = (
|
||||
kwargs.get("stacklevel", 1) + STACKLEVEL_OFFSET
|
||||
)
|
||||
|
||||
self.logger._log(level, msg, args, **kwargs)
|
||||
|
||||
def isEnabledFor(self, level: int) -> bool:
|
||||
"""Is this logger enabled for level 'level'?"""
|
||||
|
||||
if self.logger.manager.disable >= level:
|
||||
return False
|
||||
return level >= self.getEffectiveLevel()
|
||||
|
||||
def getEffectiveLevel(self) -> int:
|
||||
"""What's the effective level for this logger?"""
|
||||
|
||||
level = self._echo_map[self.echo]
|
||||
if level == logging.NOTSET:
|
||||
level = self.logger.getEffectiveLevel()
|
||||
return level
|
||||
|
||||
|
||||
def instance_logger(
|
||||
instance: Identified, echoflag: _EchoFlagType = None
|
||||
) -> None:
|
||||
"""create a logger for an instance that implements :class:`.Identified`."""
|
||||
|
||||
if instance.logging_name:
|
||||
name = "%s.%s" % (
|
||||
_qual_logger_name_for_cls(instance.__class__),
|
||||
instance.logging_name,
|
||||
)
|
||||
else:
|
||||
name = _qual_logger_name_for_cls(instance.__class__)
|
||||
|
||||
instance._echo = echoflag # type: ignore
|
||||
|
||||
logger: Union[logging.Logger, InstanceLogger]
|
||||
|
||||
if echoflag in (False, None):
|
||||
# if no echo setting or False, return a Logger directly,
|
||||
# avoiding overhead of filtering
|
||||
logger = logging.getLogger(name)
|
||||
else:
|
||||
# if a specified echo flag, return an EchoLogger,
|
||||
# which checks the flag, overrides normal log
|
||||
# levels by calling logger._log()
|
||||
logger = InstanceLogger(echoflag, name)
|
||||
|
||||
instance.logger = logger # type: ignore
|
||||
|
||||
|
||||
class echo_property:
|
||||
__doc__ = """\
|
||||
When ``True``, enable log output for this element.
|
||||
|
||||
This has the effect of setting the Python logging level for the namespace
|
||||
of this element's class and object reference. A value of boolean ``True``
|
||||
indicates that the loglevel ``logging.INFO`` will be set for the logger,
|
||||
whereas the string value ``debug`` will set the loglevel to
|
||||
``logging.DEBUG``.
|
||||
"""
|
||||
|
||||
@overload
|
||||
def __get__(
|
||||
self, instance: Literal[None], owner: Type[Identified]
|
||||
) -> echo_property: ...
|
||||
|
||||
@overload
|
||||
def __get__(
|
||||
self, instance: Identified, owner: Type[Identified]
|
||||
) -> _EchoFlagType: ...
|
||||
|
||||
def __get__(
|
||||
self, instance: Optional[Identified], owner: Type[Identified]
|
||||
) -> Union[echo_property, _EchoFlagType]:
|
||||
if instance is None:
|
||||
return self
|
||||
else:
|
||||
return instance._echo
|
||||
|
||||
def __set__(self, instance: Identified, value: _EchoFlagType) -> None:
|
||||
instance_logger(instance, echoflag=value)
|
||||
Reference in New Issue
Block a user