arpakitlib 1.8.267__py3-none-any.whl → 1.8.269__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- arpakitlib/ar_base_worker_util.py +6 -2
- arpakitlib/ar_sqlalchemy_drop_check_constraints.py +82 -0
- arpakitlib/ar_sqlalchemy_util.py +4 -0
- {arpakitlib-1.8.267.dist-info → arpakitlib-1.8.269.dist-info}/METADATA +1 -1
- {arpakitlib-1.8.267.dist-info → arpakitlib-1.8.269.dist-info}/RECORD +8 -7
- {arpakitlib-1.8.267.dist-info → arpakitlib-1.8.269.dist-info}/LICENSE +0 -0
- {arpakitlib-1.8.267.dist-info → arpakitlib-1.8.269.dist-info}/WHEEL +0 -0
- {arpakitlib-1.8.267.dist-info → arpakitlib-1.8.269.dist-info}/entry_points.txt +0 -0
@@ -75,8 +75,10 @@ class BaseWorker(ABC):
|
|
75
75
|
def sync_on_error(self, exception: Exception, **kwargs):
|
76
76
|
pass
|
77
77
|
|
78
|
-
def sync_safe_run(self):
|
78
|
+
def sync_safe_run(self, *, timeout_before_run: timedelta | None = None):
|
79
79
|
self._logger.info("start")
|
80
|
+
if timeout_before_run is not None:
|
81
|
+
sync_safe_sleep(timeout_before_run)
|
80
82
|
try:
|
81
83
|
self.sync_on_startup()
|
82
84
|
except Exception as exception:
|
@@ -117,8 +119,10 @@ class BaseWorker(ABC):
|
|
117
119
|
async def async_on_error(self, exception: Exception, **kwargs):
|
118
120
|
pass
|
119
121
|
|
120
|
-
async def async_safe_run(self):
|
122
|
+
async def async_safe_run(self, *, timeout_before_run: timedelta | None = None):
|
121
123
|
self._logger.info("start async_safe_run")
|
124
|
+
if timeout_before_run is not None:
|
125
|
+
await async_safe_sleep(timeout_before_run)
|
122
126
|
try:
|
123
127
|
await self.async_on_startup()
|
124
128
|
except Exception as exception:
|
@@ -0,0 +1,82 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from typing import Optional
|
4
|
+
|
5
|
+
import sqlalchemy
|
6
|
+
from sqlalchemy.engine import Engine
|
7
|
+
from sqlalchemy.orm import DeclarativeBase
|
8
|
+
|
9
|
+
|
10
|
+
def _quote_ident_pg(ident: str) -> str:
|
11
|
+
# простое кавычирование для PG (экранируем двойные кавычки)
|
12
|
+
return '"' + ident.replace('"', '""') + '"'
|
13
|
+
|
14
|
+
|
15
|
+
def _quote_ident_mysql(ident: str) -> str:
|
16
|
+
# простое кавычирование для MySQL/MariaDB (экранируем обратные апострофы)
|
17
|
+
return '`' + ident.replace('`', '``') + '`'
|
18
|
+
|
19
|
+
|
20
|
+
def _qualified_name(
|
21
|
+
schema: Optional[str], table: str, dialect_name: str
|
22
|
+
) -> str:
|
23
|
+
if dialect_name == "postgresql":
|
24
|
+
q = _quote_ident_pg
|
25
|
+
elif dialect_name in {"mysql", "mariadb"}:
|
26
|
+
q = _quote_ident_mysql
|
27
|
+
else:
|
28
|
+
# по умолчанию без кавычек — но мы не должны сюда попасть,
|
29
|
+
# поскольку ниже ограничиваем поддержанные диалекты.
|
30
|
+
q = lambda x: x
|
31
|
+
|
32
|
+
if schema:
|
33
|
+
return f"{q(schema)}.{q(table)}"
|
34
|
+
return q(table)
|
35
|
+
|
36
|
+
|
37
|
+
def drop_sqlalchemy_check_constraints(*, base_: type[DeclarativeBase], engine: Engine) -> None:
|
38
|
+
"""
|
39
|
+
Удаляет ВСЕ существующие в БД CHECK-ограничения для таблиц из base_.metadata,
|
40
|
+
выполняя прямые SQL-запросы (без SQLAlchemy DDL-объектов).
|
41
|
+
|
42
|
+
Поддерживаемые диалекты:
|
43
|
+
- PostgreSQL: ALTER TABLE <sch>.<tbl> DROP CONSTRAINT <name>
|
44
|
+
- MySQL 8.0.16+/MariaDB 10.2+: ALTER TABLE <sch>.<tbl> DROP CHECK <name>
|
45
|
+
|
46
|
+
Для SQLite кидает NotImplementedError.
|
47
|
+
"""
|
48
|
+
|
49
|
+
if engine.dialect.name == "sqlite":
|
50
|
+
raise NotImplementedError(
|
51
|
+
"Удаление CHECK-констреинтов прямыми запросами для SQLite не поддержано: "
|
52
|
+
"в большинстве версий требуется пересоздание таблицы."
|
53
|
+
)
|
54
|
+
if engine.dialect.name not in {"postgresql", "mysql", "mariadb"}:
|
55
|
+
raise NotImplementedError(f"Пока не реализовано для диалекта: {engine.dialect.name}")
|
56
|
+
|
57
|
+
with engine.begin() as conn:
|
58
|
+
conn_inspection_ = sqlalchemy.inspect(conn)
|
59
|
+
|
60
|
+
for table in base_.metadata.tables.values():
|
61
|
+
fqtn = _qualified_name(table.schema, table.name, engine.dialect.name)
|
62
|
+
|
63
|
+
# берём ВСЕ реальные CHECK-и из базы
|
64
|
+
checks = conn_inspection_.get_check_constraints(table.name, schema=table.schema)
|
65
|
+
|
66
|
+
for check_ in checks:
|
67
|
+
name = check_.get("name")
|
68
|
+
if not name:
|
69
|
+
# На всякий случай: без имени нам нечего дропать безопасно
|
70
|
+
# (в PG/ MySQL синтаксис требует имя).
|
71
|
+
continue
|
72
|
+
|
73
|
+
if engine.dialect.name == "postgresql":
|
74
|
+
ident = _quote_ident_pg(name)
|
75
|
+
sql = f"ALTER TABLE {fqtn} DROP CONSTRAINT {ident}"
|
76
|
+
else: # mysql / mariadb
|
77
|
+
ident = _quote_ident_mysql(name)
|
78
|
+
# В MySQL/MariaDB именно DROP CHECK <name>
|
79
|
+
sql = f"ALTER TABLE {fqtn} DROP CHECK {ident}"
|
80
|
+
|
81
|
+
# выполняем прямой SQL-запрос
|
82
|
+
conn.exec_driver_sql(sql)
|
arpakitlib/ar_sqlalchemy_util.py
CHANGED
@@ -305,6 +305,10 @@ class SQLAlchemyDb:
|
|
305
305
|
from arpakitlib.ar_ensure_sqlalchemy_check_constraints import ensure_sqlalchemy_check_constraints
|
306
306
|
ensure_sqlalchemy_check_constraints(base_=self.base_dbm, engine=self.engine)
|
307
307
|
|
308
|
+
def drop_check_constraints(self):
|
309
|
+
from arpakitlib.ar_sqlalchemy_drop_check_constraints import drop_sqlalchemy_check_constraints
|
310
|
+
drop_sqlalchemy_check_constraints(base_=self.base_dbm, engine=self.engine)
|
311
|
+
|
308
312
|
def init(self, ensure_check_constraints: bool = True):
|
309
313
|
self.base_dbm.metadata.create_all(bind=self.engine, checkfirst=True)
|
310
314
|
if ensure_check_constraints:
|
@@ -384,7 +384,7 @@ arpakitlib/ar_arpakit_schedule_uust_api_client_util.py,sha256=MRPaF31CRhYA45ldPn
|
|
384
384
|
arpakitlib/ar_arpakit_schedule_uust_site_util.py,sha256=8wLct9Gd4MWkXzB6nSmETAwTPLw8lfpWgx0LoWSAOvg,1643
|
385
385
|
arpakitlib/ar_arpakitlib_cli_util.py,sha256=RJGcfEZ_q74FJ4tqdXvt7xQpShTszOvKu1mbp3D8qzw,2599
|
386
386
|
arpakitlib/ar_base64_util.py,sha256=udSSpeXMZx0JgQknl4hQgZ8kr1Ps_aQOloIXu4T9dMQ,1286
|
387
|
-
arpakitlib/ar_base_worker_util.py,sha256=
|
387
|
+
arpakitlib/ar_base_worker_util.py,sha256=QXrk_bnxgxtbmz8YhfShxuLMMJEz2HK2KZpYeFcRm1I,6267
|
388
388
|
arpakitlib/ar_blank_util.py,sha256=qFUdY8usL_pRYamz8Rw1fW3fzNIgrLmpdYP8q-_PQvw,2281
|
389
389
|
arpakitlib/ar_cache_file_util.py,sha256=Fo2pH-Zqm966KWFBHG_pbiySGZvhIFCYqy7k1weRfJ0,3476
|
390
390
|
arpakitlib/ar_class_util.py,sha256=i76pQW_7k_S2m_DlQh6xNjtggv9Col3WSx9W_bwk98E,722
|
@@ -426,12 +426,13 @@ arpakitlib/ar_schedule_uust_api_client_util.py,sha256=rXI2_3OTaIBgR-GixM1Ti-Ue1f
|
|
426
426
|
arpakitlib/ar_settings_util.py,sha256=Y5wi_cmsjDjfJpM0VJHjbo0NoVPKfypKaD1USowwDtQ,1327
|
427
427
|
arpakitlib/ar_sleep_util.py,sha256=ggaj7ML6QK_ADsHMcyu6GUmUpQ_9B9n-SKYH17h-9lM,1045
|
428
428
|
arpakitlib/ar_sqladmin_util.py,sha256=SEoaowAPF3lhxPsNjwmOymNJ55Ty9rmzvsDm7gD5Ceo,861
|
429
|
-
arpakitlib/
|
429
|
+
arpakitlib/ar_sqlalchemy_drop_check_constraints.py,sha256=XEqnMrIwSYasW_UOJ8xU-JhsVrcYeyehalFuSvmJMak,3518
|
430
|
+
arpakitlib/ar_sqlalchemy_util.py,sha256=EMMaoVerrDaFXCCwH2BbbpaVr_oKp4nDlbnoJRJg_84,16404
|
430
431
|
arpakitlib/ar_str_util.py,sha256=2lGpnXDf2h1cBZpVf5i1tX_HCv5iBd6IGnrCw4QWWlY,4350
|
431
432
|
arpakitlib/ar_type_util.py,sha256=Cs_tef-Fc5xeyAF54KgISCsP11NHyzIsglm4S3Xx7iM,4049
|
432
433
|
arpakitlib/ar_yookassa_api_client_util.py,sha256=VozuZeCJjmLd1zj2BdC9WfiAQ3XYOrIMsdpNK-AUlm0,5347
|
433
|
-
arpakitlib-1.8.
|
434
|
-
arpakitlib-1.8.
|
435
|
-
arpakitlib-1.8.
|
436
|
-
arpakitlib-1.8.
|
437
|
-
arpakitlib-1.8.
|
434
|
+
arpakitlib-1.8.269.dist-info/LICENSE,sha256=GPEDQMam2r7FSTYqM1mm7aKnxLaWcBotH7UvQtea-ec,11355
|
435
|
+
arpakitlib-1.8.269.dist-info/METADATA,sha256=bA31Hw4OoYrLzkLSB8hVlkHmS77vA_TS00PKwkJe28g,3919
|
436
|
+
arpakitlib-1.8.269.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
437
|
+
arpakitlib-1.8.269.dist-info/entry_points.txt,sha256=36xqR3PJFT2kuwjkM_EqoIy0qFUDPKSm_mJaI7emewE,87
|
438
|
+
arpakitlib-1.8.269.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|