1
0
mirror of https://gitlab.com/MoonTestUse1/AdministrationItDepartmens.git synced 2025-08-14 00:25:46 +02:00

Проверка 09.02.2025

This commit is contained in:
MoonTestUse1
2025-02-09 01:11:49 +06:00
parent ce52f8a23a
commit 0aa3ef8fc2
5827 changed files with 14316 additions and 1906434 deletions

View File

@@ -1,10 +1,9 @@
# ext/compiler.py
# Copyright (C) 2005-2024 the SQLAlchemy authors and contributors
# 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
r"""Provides an API for creation of custom ClauseElements and compilers.
@@ -18,9 +17,11 @@ more callables defining its compilation::
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.sql.expression import ColumnClause
class MyColumn(ColumnClause):
inherit_cache = True
@compiles(MyColumn)
def compile_mycolumn(element, compiler, **kw):
return "[%s]" % element.name
@@ -32,10 +33,12 @@ when the object is compiled to a string::
from sqlalchemy import select
s = select(MyColumn('x'), MyColumn('y'))
s = select(MyColumn("x"), MyColumn("y"))
print(str(s))
Produces::
Produces:
.. sourcecode:: sql
SELECT [x], [y]
@@ -47,6 +50,7 @@ invoked for the dialect in use::
from sqlalchemy.schema import DDLElement
class AlterColumn(DDLElement):
inherit_cache = False
@@ -54,14 +58,18 @@ invoked for the dialect in use::
self.column = column
self.cmd = cmd
@compiles(AlterColumn)
def visit_alter_column(element, compiler, **kw):
return "ALTER COLUMN %s ..." % element.column.name
@compiles(AlterColumn, 'postgresql')
@compiles(AlterColumn, "postgresql")
def visit_alter_column(element, compiler, **kw):
return "ALTER TABLE %s ALTER COLUMN %s ..." % (element.table.name,
element.column.name)
return "ALTER TABLE %s ALTER COLUMN %s ..." % (
element.table.name,
element.column.name,
)
The second ``visit_alter_table`` will be invoked when any ``postgresql``
dialect is used.
@@ -81,6 +89,7 @@ method which can be used for compilation of embedded attributes::
from sqlalchemy.sql.expression import Executable, ClauseElement
class InsertFromSelect(Executable, ClauseElement):
inherit_cache = False
@@ -88,20 +97,27 @@ method which can be used for compilation of embedded attributes::
self.table = table
self.select = select
@compiles(InsertFromSelect)
def visit_insert_from_select(element, compiler, **kw):
return "INSERT INTO %s (%s)" % (
compiler.process(element.table, asfrom=True, **kw),
compiler.process(element.select, **kw)
compiler.process(element.select, **kw),
)
insert = InsertFromSelect(t1, select(t1).where(t1.c.x>5))
insert = InsertFromSelect(t1, select(t1).where(t1.c.x > 5))
print(insert)
Produces::
Produces (formatted for readability):
"INSERT INTO mytable (SELECT mytable.x, mytable.y, mytable.z
FROM mytable WHERE mytable.x > :x_1)"
.. sourcecode:: sql
INSERT INTO mytable (
SELECT mytable.x, mytable.y, mytable.z
FROM mytable
WHERE mytable.x > :x_1
)
.. note::
@@ -121,11 +137,10 @@ below where we generate a CHECK constraint that embeds a SQL expression::
@compiles(MyConstraint)
def compile_my_constraint(constraint, ddlcompiler, **kw):
kw['literal_binds'] = True
kw["literal_binds"] = True
return "CONSTRAINT %s CHECK (%s)" % (
constraint.name,
ddlcompiler.sql_compiler.process(
constraint.expression, **kw)
ddlcompiler.sql_compiler.process(constraint.expression, **kw),
)
Above, we add an additional flag to the process step as called by
@@ -153,6 +168,7 @@ an endless loop. Such as, to add "prefix" to all insert statements::
from sqlalchemy.sql.expression import Insert
@compiles(Insert)
def prefix_inserts(insert, compiler, **kw):
return compiler.visit_insert(insert.prefix_with("some prefix"), **kw)
@@ -168,17 +184,16 @@ Changing Compilation of Types
``compiler`` works for types, too, such as below where we implement the
MS-SQL specific 'max' keyword for ``String``/``VARCHAR``::
@compiles(String, 'mssql')
@compiles(VARCHAR, 'mssql')
@compiles(String, "mssql")
@compiles(VARCHAR, "mssql")
def compile_varchar(element, compiler, **kw):
if element.length == 'max':
if element.length == "max":
return "VARCHAR('max')"
else:
return compiler.visit_VARCHAR(element, **kw)
foo = Table('foo', metadata,
Column('data', VARCHAR('max'))
)
foo = Table("foo", metadata, Column("data", VARCHAR("max")))
Subclassing Guidelines
======================
@@ -216,18 +231,23 @@ A synopsis is as follows:
from sqlalchemy.sql.expression import FunctionElement
class coalesce(FunctionElement):
name = 'coalesce'
name = "coalesce"
inherit_cache = True
@compiles(coalesce)
def compile(element, compiler, **kw):
return "coalesce(%s)" % compiler.process(element.clauses, **kw)
@compiles(coalesce, 'oracle')
@compiles(coalesce, "oracle")
def compile(element, compiler, **kw):
if len(element.clauses) > 2:
raise TypeError("coalesce only supports two arguments on Oracle")
raise TypeError(
"coalesce only supports two arguments on " "Oracle Database"
)
return "nvl(%s)" % compiler.process(element.clauses, **kw)
* :class:`.ExecutableDDLElement` - The root of all DDL expressions,
@@ -281,6 +301,7 @@ for example to the "synopsis" example indicated previously::
class MyColumn(ColumnClause):
inherit_cache = True
@compiles(MyColumn)
def compile_mycolumn(element, compiler, **kw):
return "[%s]" % element.name
@@ -319,11 +340,12 @@ caching::
self.table = table
self.select = select
@compiles(InsertFromSelect)
def visit_insert_from_select(element, compiler, **kw):
return "INSERT INTO %s (%s)" % (
compiler.process(element.table, asfrom=True, **kw),
compiler.process(element.select, **kw)
compiler.process(element.select, **kw),
)
While it is also possible that the above ``InsertFromSelect`` could be made to
@@ -359,28 +381,32 @@ For PostgreSQL and Microsoft SQL Server::
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.types import DateTime
class utcnow(expression.FunctionElement):
type = DateTime()
inherit_cache = True
@compiles(utcnow, 'postgresql')
@compiles(utcnow, "postgresql")
def pg_utcnow(element, compiler, **kw):
return "TIMEZONE('utc', CURRENT_TIMESTAMP)"
@compiles(utcnow, 'mssql')
@compiles(utcnow, "mssql")
def ms_utcnow(element, compiler, **kw):
return "GETUTCDATE()"
Example usage::
from sqlalchemy import (
Table, Column, Integer, String, DateTime, MetaData
)
from sqlalchemy import Table, Column, Integer, String, DateTime, MetaData
metadata = MetaData()
event = Table("event", metadata,
event = Table(
"event",
metadata,
Column("id", Integer, primary_key=True),
Column("description", String(50), nullable=False),
Column("timestamp", DateTime, server_default=utcnow())
Column("timestamp", DateTime, server_default=utcnow()),
)
"GREATEST" function
@@ -395,30 +421,30 @@ accommodates two arguments::
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.types import Numeric
class greatest(expression.FunctionElement):
type = Numeric()
name = 'greatest'
name = "greatest"
inherit_cache = True
@compiles(greatest)
def default_greatest(element, compiler, **kw):
return compiler.visit_function(element)
@compiles(greatest, 'sqlite')
@compiles(greatest, 'mssql')
@compiles(greatest, 'oracle')
@compiles(greatest, "sqlite")
@compiles(greatest, "mssql")
@compiles(greatest, "oracle")
def case_greatest(element, compiler, **kw):
arg1, arg2 = list(element.clauses)
return compiler.process(case((arg1 > arg2, arg1), else_=arg2), **kw)
Example usage::
Session.query(Account).\
filter(
greatest(
Account.checking_balance,
Account.savings_balance) > 10000
)
Session.query(Account).filter(
greatest(Account.checking_balance, Account.savings_balance) > 10000
)
"false" expression
------------------
@@ -429,16 +455,19 @@ don't have a "false" constant::
from sqlalchemy.sql import expression
from sqlalchemy.ext.compiler import compiles
class sql_false(expression.ColumnElement):
inherit_cache = True
@compiles(sql_false)
def default_false(element, compiler, **kw):
return "false"
@compiles(sql_false, 'mssql')
@compiles(sql_false, 'mysql')
@compiles(sql_false, 'oracle')
@compiles(sql_false, "mssql")
@compiles(sql_false, "mysql")
@compiles(sql_false, "oracle")
def int_false(element, compiler, **kw):
return "0"
@@ -448,19 +477,33 @@ Example usage::
exp = union_all(
select(users.c.name, sql_false().label("enrolled")),
select(customers.c.name, customers.c.enrolled)
select(customers.c.name, customers.c.enrolled),
)
"""
from __future__ import annotations
from typing import Any
from typing import Callable
from typing import Dict
from typing import Type
from typing import TYPE_CHECKING
from typing import TypeVar
from .. import exc
from ..sql import sqltypes
if TYPE_CHECKING:
from ..sql.compiler import SQLCompiler
def compiles(class_, *specs):
_F = TypeVar("_F", bound=Callable[..., Any])
def compiles(class_: Type[Any], *specs: str) -> Callable[[_F], _F]:
"""Register a function as a compiler for a
given :class:`_expression.ClauseElement` type."""
def decorate(fn):
def decorate(fn: _F) -> _F:
# get an existing @compiles handler
existing = class_.__dict__.get("_compiler_dispatcher", None)
@@ -473,7 +516,9 @@ def compiles(class_, *specs):
if existing_dispatch:
def _wrap_existing_dispatch(element, compiler, **kw):
def _wrap_existing_dispatch(
element: Any, compiler: SQLCompiler, **kw: Any
) -> Any:
try:
return existing_dispatch(element, compiler, **kw)
except exc.UnsupportedCompilationError as uce:
@@ -505,7 +550,7 @@ def compiles(class_, *specs):
return decorate
def deregister(class_):
def deregister(class_: Type[Any]) -> None:
"""Remove all custom compilers associated with a given
:class:`_expression.ClauseElement` type.
@@ -517,10 +562,10 @@ def deregister(class_):
class _dispatcher:
def __init__(self):
self.specs = {}
def __init__(self) -> None:
self.specs: Dict[str, Callable[..., Any]] = {}
def __call__(self, element, compiler, **kw):
def __call__(self, element: Any, compiler: SQLCompiler, **kw: Any) -> Any:
# TODO: yes, this could also switch off of DBAPI in use.
fn = self.specs.get(compiler.dialect.name, None)
if not fn: