arpakitlib 1.8.219__py3-none-any.whl → 1.8.221__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.
@@ -1,11 +1,10 @@
1
1
  from typing import Type
2
2
 
3
- from pydantic import BaseModel
4
-
5
3
  from arpakitlib.ar_sqlalchemy_util import BaseDBM
4
+ from pydantic import BaseModel
6
5
 
7
6
 
8
- def schema_from_dbm(*, schema: Type[BaseModel], dbm: BaseDBM, **kwargs) -> BaseModel:
7
+ def create_obj_schema_from_dbm(*, schema: Type[BaseModel], dbm: BaseDBM, **kwargs) -> BaseModel:
9
8
  return schema.model_validate(dbm.simple_dict(
10
9
  include_columns_and_sd_properties=schema.model_fields.keys()
11
10
  ))
@@ -1,8 +1,12 @@
1
1
  import asyncio
2
2
 
3
+ from arpakitlib.pydantic_schema_from_sqlalchemy_model import pydantic_schema_from_sqlalchemy_model
4
+ from project.sqlalchemy_db_.sqlalchemy_model import UserDBM
5
+
3
6
 
4
7
  def __sandbox():
5
- pass
8
+ a = pydantic_schema_from_sqlalchemy_model(sqlalchemy_model=UserDBM, include_defaults=True)
9
+ print(a())
6
10
 
7
11
 
8
12
  async def __async_sandbox():
@@ -89,32 +89,54 @@ class BaseDBM(DeclarativeBase):
89
89
  def get_relationship_names_(
90
90
  cls,
91
91
  *,
92
+ exclude_one_to_many: bool = False,
93
+ exclude_many_to_one: bool = False,
94
+ exclude_many_to_many: bool = False,
95
+ exclude_viewonly: bool = False,
92
96
  exclude_names: list[str] | None = None
93
97
  ) -> list[str]:
94
98
  if exclude_names is None:
95
99
  exclude_names = []
96
100
  res = []
97
- for c in inspect(cls).relationships:
98
- if c.key in exclude_names:
101
+ for r in inspect(cls).relationships:
102
+ if r.key in exclude_names:
99
103
  continue
100
- res.append(c.key)
104
+ if exclude_viewonly and r.viewonly:
105
+ continue
106
+ if exclude_one_to_many and r.direction is sqlalchemy.orm.ONETOMANY:
107
+ continue
108
+ if exclude_many_to_one and r.direction is sqlalchemy.orm.MANYTOONE:
109
+ continue
110
+ if exclude_many_to_many and r.direction is sqlalchemy.orm.MANYTOMANY:
111
+ continue
112
+ res.append(r.key)
101
113
  return res
102
114
 
103
115
  @classmethod
104
116
  def get_column_and_relationship_names_(
105
117
  cls,
106
118
  *,
119
+
107
120
  include_column_names: bool = True,
108
121
  include_column_pk: bool = True,
109
122
  exclude_column_names: list[str] | None = None,
123
+
110
124
  include_relationship_names: bool = True,
125
+ exclude_one_to_many: bool = False,
126
+ exclude_many_to_one: bool = False,
127
+ exclude_many_to_many: bool = False,
111
128
  exclude_relationship_names: list[str] | None = None,
112
129
  ) -> list[str]:
113
130
  res = []
114
131
  if include_column_names:
115
132
  res += cls.get_column_names_(include_pk=include_column_pk, exclude_names=exclude_column_names)
116
133
  if include_relationship_names:
117
- res += cls.get_relationship_names_(exclude_names=exclude_relationship_names)
134
+ res += cls.get_relationship_names_(
135
+ exclude_names=exclude_relationship_names,
136
+ exclude_one_to_many=exclude_one_to_many,
137
+ exclude_many_to_one=exclude_many_to_one,
138
+ exclude_many_to_many=exclude_many_to_many,
139
+ )
118
140
  return res
119
141
 
120
142
  @classmethod
@@ -0,0 +1,91 @@
1
+ import datetime as dt
2
+ from typing import Any, Optional
3
+
4
+ from pydantic import BaseModel, Field
5
+ from sqlalchemy import inspect
6
+ from sqlalchemy.orm import ColumnProperty
7
+ from sqlalchemy.sql.sqltypes import (
8
+ Boolean, Integer, BigInteger, SmallInteger,
9
+ String, Text, Unicode, UnicodeText,
10
+ DateTime, Date, Time,
11
+ Float, Numeric, DECIMAL, LargeBinary, JSON
12
+ )
13
+
14
+ _SQLA_TYPE_MAP = {
15
+ Boolean: bool,
16
+ Integer: int,
17
+ BigInteger: int,
18
+ SmallInteger: int,
19
+ Float: float,
20
+ Numeric: float,
21
+ DECIMAL: float,
22
+ String: str,
23
+ Unicode: str,
24
+ Text: str,
25
+ UnicodeText: str,
26
+ LargeBinary: bytes,
27
+ JSON: dict,
28
+ DateTime: dt.datetime,
29
+ Date: dt.date,
30
+ Time: dt.time,
31
+ }
32
+
33
+
34
+ def _python_type_from_col(col) -> type | str:
35
+ try:
36
+ return col.type.python_type
37
+ except Exception:
38
+ for sa_t, py_t in _SQLA_TYPE_MAP.items():
39
+ if isinstance(col.type, sa_t):
40
+ return py_t
41
+ return Any
42
+
43
+
44
+ def pydantic_schema_from_sqlalchemy_model(
45
+ sqlalchemy_model: type,
46
+ *,
47
+ name: str | None = None,
48
+ base_model: type[BaseModel] = BaseModel,
49
+ include_defaults: bool = False,
50
+ exclude_column_names: list[str] | None = None,
51
+ ) -> type[BaseModel]:
52
+ """
53
+ Генерирует Pydantic-модель только из колонок SQLAlchemy-модели.
54
+ - include_defaults: добавлять ли default/server_default.
55
+ - exclude_column_names: список имён колонок, которые нужно пропустить.
56
+ """
57
+ mapper = inspect(sqlalchemy_model).mapper
58
+ model_name = name or f"{sqlalchemy_model.__name__}Schema"
59
+
60
+ annotations: dict[str, Any] = {}
61
+ attrs: dict[str, Any] = {}
62
+ exclude_column_names = set(exclude_column_names or [])
63
+
64
+ for prop in mapper.attrs:
65
+ if not isinstance(prop, ColumnProperty):
66
+ continue
67
+ if prop.key in exclude_column_names:
68
+ continue
69
+
70
+ col = prop.columns[0]
71
+ py_t = _python_type_from_col(col)
72
+
73
+ # Аннотация типа
74
+ if col.nullable:
75
+ annotations[prop.key] = Optional[py_t] # type: ignore[name-defined]
76
+ else:
77
+ annotations[prop.key] = py_t
78
+
79
+ # Если нужно — добавляем дефолт
80
+ if include_defaults:
81
+ default_value = None
82
+ if col.default is not None and col.default.is_scalar:
83
+ default_value = col.default.arg
84
+ elif col.server_default is not None and getattr(col.server_default.arg, "text", None):
85
+ default_value = col.server_default.arg.text
86
+
87
+ if default_value is not None:
88
+ attrs[prop.key] = Field(default=default_value)
89
+
90
+ attrs["__annotations__"] = annotations
91
+ return type(model_name, (base_model,), attrs)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: arpakitlib
3
- Version: 1.8.219
3
+ Version: 1.8.221
4
4
  Summary: arpakitlib
5
5
  License: Apache-2.0
6
6
  Keywords: arpakitlib,arpakit,arpakit-company,arpakitcompany,arpakit_company
@@ -168,7 +168,7 @@ arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/general/common.p
168
168
  arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/general/user.py,sha256=AvYwqaowd1V_6VQjrIGxt8SwqNEgmirLcHbtSHPwWmQ,1080
169
169
  arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/general/user_token.py,sha256=iiuZXu_zo3FJX0W5qyyMGasUx-_d32yjqc_2KY3xpUA,513
170
170
  arpakitlib/_arpakit_project_template_v_5/project/api/schema/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
171
- arpakitlib/_arpakit_project_template_v_5/project/api/schema/util/schema_from_dbm.py,sha256=vq8vtttJPmtiOXWNie4OGI-psbh3jnURtq3M7asiQOk,321
171
+ arpakitlib/_arpakit_project_template_v_5/project/api/schema/util/create_obj_schema_from_dbm.py,sha256=7HizltD9MyK1nltQQHAjy69TCOuFDkkgtFJDr7DjLxU,331
172
172
  arpakitlib/_arpakit_project_template_v_5/project/api/start_api.py,sha256=P5KMtYXujQUP2uAAKgUFyCxG99Fj2vfNf1ZEm8eFH80,532
173
173
  arpakitlib/_arpakit_project_template_v_5/project/api/util.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
174
174
  arpakitlib/_arpakit_project_template_v_5/project/business_service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -229,7 +229,7 @@ arpakitlib/_arpakit_project_template_v_5/project/resource/templates/simple_email
229
229
  arpakitlib/_arpakit_project_template_v_5/project/sandbox/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
230
230
  arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_1.py,sha256=xKSp7tIBu3Ffp_kgJkwVtdam3BcoFZ44JPVHoRRaP0E,163
231
231
  arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_2.py,sha256=xKSp7tIBu3Ffp_kgJkwVtdam3BcoFZ44JPVHoRRaP0E,163
232
- arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_3.py,sha256=xKSp7tIBu3Ffp_kgJkwVtdam3BcoFZ44JPVHoRRaP0E,163
232
+ arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_3.py,sha256=tcva9-NB0irswjg6RirZ9-pmckuZwoAr8-DUiPB2ASI,424
233
233
  arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_4.py,sha256=xKSp7tIBu3Ffp_kgJkwVtdam3BcoFZ44JPVHoRRaP0E,163
234
234
  arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_5.py,sha256=xKSp7tIBu3Ffp_kgJkwVtdam3BcoFZ44JPVHoRRaP0E,163
235
235
  arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_6.py,sha256=xKSp7tIBu3Ffp_kgJkwVtdam3BcoFZ44JPVHoRRaP0E,163
@@ -411,13 +411,14 @@ arpakitlib/ar_schedule_uust_api_client_util.py,sha256=rXI2_3OTaIBgR-GixM1Ti-Ue1f
411
411
  arpakitlib/ar_settings_util.py,sha256=Y5wi_cmsjDjfJpM0VJHjbo0NoVPKfypKaD1USowwDtQ,1327
412
412
  arpakitlib/ar_sleep_util.py,sha256=ggaj7ML6QK_ADsHMcyu6GUmUpQ_9B9n-SKYH17h-9lM,1045
413
413
  arpakitlib/ar_sqladmin_util.py,sha256=SEoaowAPF3lhxPsNjwmOymNJ55Ty9rmzvsDm7gD5Ceo,861
414
- arpakitlib/ar_sqlalchemy_util.py,sha256=lJ6lMGf6tkdgdYsJAClTzW1kEem5F-NbOwXx2r__Jnw,14346
414
+ arpakitlib/ar_sqlalchemy_util.py,sha256=Ia8eR-XiB9nZWwknLqqySS5L4RlKFe1bkTZ15rpLD8U,15270
415
415
  arpakitlib/ar_str_util.py,sha256=2lGpnXDf2h1cBZpVf5i1tX_HCv5iBd6IGnrCw4QWWlY,4350
416
416
  arpakitlib/ar_type_util.py,sha256=Cs_tef-Fc5xeyAF54KgISCsP11NHyzIsglm4S3Xx7iM,4049
417
417
  arpakitlib/ar_yookassa_api_client_util.py,sha256=VozuZeCJjmLd1zj2BdC9WfiAQ3XYOrIMsdpNK-AUlm0,5347
418
418
  arpakitlib/clone_pydantic_model_fields.py,sha256=Gn9_AIjKknN1eIYK_xH_cMyff3hjOpfwRqs583-rnJs,1167
419
- arpakitlib-1.8.219.dist-info/LICENSE,sha256=GPEDQMam2r7FSTYqM1mm7aKnxLaWcBotH7UvQtea-ec,11355
420
- arpakitlib-1.8.219.dist-info/METADATA,sha256=YeogpjKj15CfLs0qYRw3PMPzeieIGTq3nn9A_WC4Jjo,3741
421
- arpakitlib-1.8.219.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
422
- arpakitlib-1.8.219.dist-info/entry_points.txt,sha256=36xqR3PJFT2kuwjkM_EqoIy0qFUDPKSm_mJaI7emewE,87
423
- arpakitlib-1.8.219.dist-info/RECORD,,
419
+ arpakitlib/pydantic_schema_from_sqlalchemy_model.py,sha256=bjLNfeJRZonvVl7pnczwL8OzxbIGawulp30K-xYY7yA,2833
420
+ arpakitlib-1.8.221.dist-info/LICENSE,sha256=GPEDQMam2r7FSTYqM1mm7aKnxLaWcBotH7UvQtea-ec,11355
421
+ arpakitlib-1.8.221.dist-info/METADATA,sha256=-RqKllIWyEjPQbbvpX2G9z6OpQwHUf15Ztn1MNOKnRw,3741
422
+ arpakitlib-1.8.221.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
423
+ arpakitlib-1.8.221.dist-info/entry_points.txt,sha256=36xqR3PJFT2kuwjkM_EqoIy0qFUDPKSm_mJaI7emewE,87
424
+ arpakitlib-1.8.221.dist-info/RECORD,,