arpakitlib 1.8.266__py3-none-any.whl → 1.8.268__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.
@@ -10,7 +10,7 @@ _ARPAKIT_LIB_MODULE_VERSION = "3.0"
10
10
  def clone_pydantic_model_fields(
11
11
  *,
12
12
  model_cls: Type[BaseModel],
13
- base_model: Type[BaseModel],
13
+ base_model: Type[BaseModel] = BaseModel,
14
14
  fields_to_remove: Iterable[str] | None = None,
15
15
  new_class_name: str | None = None,
16
16
  class_name_prefix: str | None = "Cloned"
@@ -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)
@@ -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:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: arpakitlib
3
- Version: 1.8.266
3
+ Version: 1.8.268
4
4
  Summary: arpakitlib
5
5
  License: Apache-2.0
6
6
  Keywords: arpakitlib,arpakit,arpakit-company,arpakitcompany,arpakit_company
@@ -388,7 +388,7 @@ arpakitlib/ar_base_worker_util.py,sha256=e-Vj9w1D-59KN3Zz7TQlOB2lW4fZphJlsPpFkmX
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
391
- arpakitlib/ar_clone_pydantic_model_fields.py,sha256=Tz609Z-HH23bDxIBPbHEeKwMLoLtrS9qHntEUe7ClDc,1441
391
+ arpakitlib/ar_clone_pydantic_model_fields.py,sha256=5i77NGEjnY2ppk_Ot179egQGNDvg7zre8NBl5Es1nkg,1453
392
392
  arpakitlib/ar_datetime_util.py,sha256=Xe1NiT9oPQzNSG7RVRkhukhbg4i-hhS5ImmV7sPUc8o,971
393
393
  arpakitlib/ar_dict_util.py,sha256=oet-9AJEjQZfG_EI82BuYW0jdW2NQxKjPXol_nfTXjw,447
394
394
  arpakitlib/ar_dream_ai_api_client_util.py,sha256=Z1oii_XSsgunYx17SdcHl54S4KPQti7-MJs0xXZ8vL0,2830
@@ -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/ar_sqlalchemy_util.py,sha256=FDva9onjtCPrYZYIHHb93NMwD1WlmaORjiWgPRJQKoU,16180
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.266.dist-info/LICENSE,sha256=GPEDQMam2r7FSTYqM1mm7aKnxLaWcBotH7UvQtea-ec,11355
434
- arpakitlib-1.8.266.dist-info/METADATA,sha256=7Bv4WfJmbcKL7mPKzo_ubrItgW1icyVCL-N__viFjoY,3919
435
- arpakitlib-1.8.266.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
436
- arpakitlib-1.8.266.dist-info/entry_points.txt,sha256=36xqR3PJFT2kuwjkM_EqoIy0qFUDPKSm_mJaI7emewE,87
437
- arpakitlib-1.8.266.dist-info/RECORD,,
434
+ arpakitlib-1.8.268.dist-info/LICENSE,sha256=GPEDQMam2r7FSTYqM1mm7aKnxLaWcBotH7UvQtea-ec,11355
435
+ arpakitlib-1.8.268.dist-info/METADATA,sha256=loF6G97KNy-SAoM8vY2UPZam4JHIjGfdBb0hwjKkUTI,3919
436
+ arpakitlib-1.8.268.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
437
+ arpakitlib-1.8.268.dist-info/entry_points.txt,sha256=36xqR3PJFT2kuwjkM_EqoIy0qFUDPKSm_mJaI7emewE,87
438
+ arpakitlib-1.8.268.dist-info/RECORD,,