half-orm-dev 0.16.0a1__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.
- half_orm_dev/__init__.py +0 -0
- half_orm_dev/changelog.py +117 -0
- half_orm_dev/cli_extension.py +171 -0
- half_orm_dev/database.py +127 -0
- half_orm_dev/db_conn.py +134 -0
- half_orm_dev/hgit.py +202 -0
- half_orm_dev/hop.py +167 -0
- half_orm_dev/manifest.py +43 -0
- half_orm_dev/modules.py +357 -0
- half_orm_dev/patch.py +348 -0
- half_orm_dev/patches/0/1/0/00_half_orm_meta.database.sql +34 -0
- half_orm_dev/patches/0/1/0/01_alter_half_orm_meta.hop_release.sql +2 -0
- half_orm_dev/patches/0/1/0/02_half_orm_meta.view.hop_penultimate_release.sql +3 -0
- half_orm_dev/patches/log +2 -0
- half_orm_dev/patches/sql/half_orm_meta.sql +208 -0
- half_orm_dev/repo.py +266 -0
- half_orm_dev/templates/.gitignore +14 -0
- half_orm_dev/templates/MANIFEST.in +1 -0
- half_orm_dev/templates/Pipfile +13 -0
- half_orm_dev/templates/README +25 -0
- half_orm_dev/templates/base_test +26 -0
- half_orm_dev/templates/init_module_template +6 -0
- half_orm_dev/templates/module_template_1 +12 -0
- half_orm_dev/templates/module_template_2 +5 -0
- half_orm_dev/templates/module_template_3 +3 -0
- half_orm_dev/templates/relation_test +19 -0
- half_orm_dev/templates/setup.py +81 -0
- half_orm_dev/templates/sql_adapter +9 -0
- half_orm_dev/templates/warning +12 -0
- half_orm_dev/utils.py +12 -0
- half_orm_dev/version.txt +1 -0
- half_orm_dev-0.16.0a1.dist-info/METADATA +314 -0
- half_orm_dev-0.16.0a1.dist-info/RECORD +38 -0
- half_orm_dev-0.16.0a1.dist-info/WHEEL +5 -0
- half_orm_dev-0.16.0a1.dist-info/entry_points.txt +2 -0
- half_orm_dev-0.16.0a1.dist-info/licenses/AUTHORS +3 -0
- half_orm_dev-0.16.0a1.dist-info/licenses/LICENSE +14 -0
- half_orm_dev-0.16.0a1.dist-info/top_level.txt +1 -0
half_orm_dev/modules.py
ADDED
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
#-*- coding: utf-8 -*-
|
|
3
|
+
# pylint: disable=invalid-name, protected-access
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
Generates/Patches/Synchronizes a hop Python package with a PostgreSQL database
|
|
7
|
+
with the `hop` command.
|
|
8
|
+
|
|
9
|
+
Initiate a new project and repository with the `hop create <project_name>` command.
|
|
10
|
+
The <project_name> directory should not exist when using this command.
|
|
11
|
+
|
|
12
|
+
In the dbname directory generated, the hop command helps you patch, test and
|
|
13
|
+
deal with CI.
|
|
14
|
+
|
|
15
|
+
TODO:
|
|
16
|
+
On the 'devel' or any private branch hop applies patches if any, runs tests.
|
|
17
|
+
On the 'main' or 'master' branch, hop checks that your git repo is in sync with
|
|
18
|
+
the remote origin, synchronizes with devel branch if needed and tags your git
|
|
19
|
+
history with the last release applied.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
import importlib
|
|
23
|
+
import os
|
|
24
|
+
import re
|
|
25
|
+
import shutil
|
|
26
|
+
import sys
|
|
27
|
+
import time
|
|
28
|
+
from keyword import iskeyword
|
|
29
|
+
from typing import Any
|
|
30
|
+
|
|
31
|
+
from half_orm.pg_meta import camel_case
|
|
32
|
+
from half_orm.model_errors import UnknownRelation
|
|
33
|
+
from half_orm.sql_adapter import SQL_ADAPTER
|
|
34
|
+
|
|
35
|
+
from half_orm import utils
|
|
36
|
+
from .utils import TEMPLATE_DIRS, hop_version
|
|
37
|
+
|
|
38
|
+
def read_template(file_name):
|
|
39
|
+
"helper"
|
|
40
|
+
with open(os.path.join(TEMPLATE_DIRS, file_name), encoding='utf-8') as file_:
|
|
41
|
+
return file_.read()
|
|
42
|
+
|
|
43
|
+
NO_APAPTER = {}
|
|
44
|
+
HO_DATACLASSES = [
|
|
45
|
+
'''import dataclasses
|
|
46
|
+
from half_orm.relation import DC_Relation
|
|
47
|
+
from half_orm.field import Field''']
|
|
48
|
+
HO_DATACLASSES_IMPORTS = set()
|
|
49
|
+
INIT_MODULE_TEMPLATE = read_template('init_module_template')
|
|
50
|
+
MODULE_TEMPLATE_1 = read_template('module_template_1')
|
|
51
|
+
MODULE_TEMPLATE_2 = read_template('module_template_2')
|
|
52
|
+
MODULE_TEMPLATE_3 = read_template('module_template_3')
|
|
53
|
+
WARNING_TEMPLATE = read_template('warning')
|
|
54
|
+
BASE_TEST = read_template('base_test')
|
|
55
|
+
TEST = read_template('relation_test')
|
|
56
|
+
SQL_ADAPTER_TEMPLATE = read_template('sql_adapter')
|
|
57
|
+
SKIP = re.compile('[A-Z]')
|
|
58
|
+
|
|
59
|
+
MODULE_FORMAT = (
|
|
60
|
+
"{rt1}" +
|
|
61
|
+
"{bc_}{global_user_s_code}{ec_}" +
|
|
62
|
+
"{rt2}" +
|
|
63
|
+
" {bc_}{user_s_class_attr} {ec_}" +
|
|
64
|
+
"{rt3}\n " +
|
|
65
|
+
"{bc_}{user_s_code}")
|
|
66
|
+
AP_EPILOG = """"""
|
|
67
|
+
INIT_PY = '__init__.py'
|
|
68
|
+
BASE_TEST_PY = 'base_test.py'
|
|
69
|
+
DO_NOT_REMOVE = [INIT_PY, BASE_TEST_PY]
|
|
70
|
+
TEST_EXT = '_test.py'
|
|
71
|
+
|
|
72
|
+
MODEL = None
|
|
73
|
+
|
|
74
|
+
def __get_full_class_name(schemaname, relationname):
|
|
75
|
+
schemaname = ''.join([elt.capitalize() for elt in schemaname.split('.')])
|
|
76
|
+
relationname = ''.join([elt.capitalize() for elt in relationname.split('_')])
|
|
77
|
+
return f'{schemaname}{relationname}'
|
|
78
|
+
|
|
79
|
+
def __get_field_desc(field_name, field):
|
|
80
|
+
#TODO: REFACTOR
|
|
81
|
+
sql_type = field._metadata['fieldtype']
|
|
82
|
+
field_desc = SQL_ADAPTER.get(sql_type)
|
|
83
|
+
if field_desc is None:
|
|
84
|
+
if not NO_APAPTER.get(sql_type):
|
|
85
|
+
NO_APAPTER[sql_type] = 0
|
|
86
|
+
NO_APAPTER[sql_type] += 1
|
|
87
|
+
field_desc = Any
|
|
88
|
+
if field_desc.__module__ != 'builtins':
|
|
89
|
+
HO_DATACLASSES_IMPORTS.add(field_desc.__module__)
|
|
90
|
+
ext = 'Any'
|
|
91
|
+
if hasattr(field_desc, '__name__'):
|
|
92
|
+
ext = field_desc.__name__
|
|
93
|
+
field_desc = f'{field_desc.__module__}.{ext}'
|
|
94
|
+
else:
|
|
95
|
+
field_desc = field_desc.__name__
|
|
96
|
+
value = 'dataclasses.field(default=None)'
|
|
97
|
+
if field._metadata['fieldtype'][0] == '_':
|
|
98
|
+
value = 'dataclasses.field(default_factory=list)'
|
|
99
|
+
field_desc = f'{field_desc} = {value}'
|
|
100
|
+
field_desc = f" {field_name}: {field_desc}"
|
|
101
|
+
error = utils.check_attribute_name(field_name)
|
|
102
|
+
if error:
|
|
103
|
+
field_desc = f'# {field_desc} FIX ME! {error}'
|
|
104
|
+
return field_desc
|
|
105
|
+
|
|
106
|
+
def __gen_dataclass(relation, fkeys):
|
|
107
|
+
rel = relation()
|
|
108
|
+
dc_name = relation._ho_dataclass_name()
|
|
109
|
+
fields = []
|
|
110
|
+
post_init = [' def __post_init__(self):']
|
|
111
|
+
for field_name, field in rel._ho_fields.items():
|
|
112
|
+
fields.append(__get_field_desc(field_name, field))
|
|
113
|
+
post_init.append(f' self.{field_name}: Field = None')
|
|
114
|
+
|
|
115
|
+
fkeys = {value:key for key, value in fkeys.items() if key != ''}
|
|
116
|
+
for key, value in rel()._ho_fkeys.items():
|
|
117
|
+
if key in fkeys:
|
|
118
|
+
fkey_alias = fkeys[key]
|
|
119
|
+
fdc_name = f'{value._FKey__relation._ho_dataclass_name()}'
|
|
120
|
+
post_init.append(f" self.{fkey_alias} = {fdc_name}")
|
|
121
|
+
return '\n'.join([f'@dataclasses.dataclass\nclass {dc_name}(DC_Relation):'] + fields + post_init)
|
|
122
|
+
|
|
123
|
+
def __get_modules_list(dir, files_list, files):
|
|
124
|
+
all_ = []
|
|
125
|
+
for file_ in files:
|
|
126
|
+
if re.findall(SKIP, file_):
|
|
127
|
+
continue
|
|
128
|
+
path_ = os.path.join(dir, file_)
|
|
129
|
+
if path_ not in files_list and file_ not in DO_NOT_REMOVE:
|
|
130
|
+
if path_.find('__pycache__') == -1 and path_.find(TEST_EXT) == -1:
|
|
131
|
+
print(f"REMOVING: {path_}")
|
|
132
|
+
os.remove(path_)
|
|
133
|
+
continue
|
|
134
|
+
if (re.findall('.py$', file_) and
|
|
135
|
+
file_ != INIT_PY and
|
|
136
|
+
file_ != '__pycache__' and
|
|
137
|
+
file_.find(TEST_EXT) == -1):
|
|
138
|
+
all_.append(file_.replace('.py', ''))
|
|
139
|
+
all_.sort()
|
|
140
|
+
return all_
|
|
141
|
+
|
|
142
|
+
def __update_init_files(package_dir, files_list, warning):
|
|
143
|
+
"""Update __all__ lists in __init__ files.
|
|
144
|
+
"""
|
|
145
|
+
for dir, _, files in os.walk(package_dir):
|
|
146
|
+
if dir == package_dir:
|
|
147
|
+
continue
|
|
148
|
+
reldir = dir.replace(package_dir, '')
|
|
149
|
+
if re.findall(SKIP, reldir):
|
|
150
|
+
continue
|
|
151
|
+
all_ = __get_modules_list(dir, files_list, files)
|
|
152
|
+
dirs = next(os.walk(dir))[1]
|
|
153
|
+
|
|
154
|
+
if len(all_) == 0 and dirs == ['__pycache__']:
|
|
155
|
+
shutil.rmtree(dir)
|
|
156
|
+
else:
|
|
157
|
+
with open(os.path.join(dir, INIT_PY), 'w', encoding='utf-8') as init_file:
|
|
158
|
+
init_file.write(f'"""{warning}"""\n\n')
|
|
159
|
+
all_ = ",\n ".join([f"'{elt}'" for elt in all_])
|
|
160
|
+
init_file.write(f'__all__ = [\n {all_}\n]\n')
|
|
161
|
+
|
|
162
|
+
def __get_inheritance_info(rel, package_name):
|
|
163
|
+
"""Returns inheritance informations for the rel relation.
|
|
164
|
+
"""
|
|
165
|
+
inheritance_import_list = []
|
|
166
|
+
inherited_classes_aliases_list = []
|
|
167
|
+
for base in rel.__class__.__bases__:
|
|
168
|
+
if base.__name__ != 'Relation':
|
|
169
|
+
inh_sfqrn = list(base._t_fqrn)
|
|
170
|
+
inh_sfqrn[0] = package_name
|
|
171
|
+
inh_cl_alias = f"{camel_case(inh_sfqrn[1])}{camel_case(inh_sfqrn[2])}"
|
|
172
|
+
inh_cl_name = f"{camel_case(inh_sfqrn[2])}"
|
|
173
|
+
from_import = f"from {'.'.join(inh_sfqrn)} import {inh_cl_name} as {inh_cl_alias}"
|
|
174
|
+
inheritance_import_list.append(from_import)
|
|
175
|
+
inherited_classes_aliases_list.append(inh_cl_alias)
|
|
176
|
+
inheritance_import = "\n".join(inheritance_import_list)
|
|
177
|
+
inherited_classes = ", ".join(inherited_classes_aliases_list)
|
|
178
|
+
if inherited_classes.strip():
|
|
179
|
+
inherited_classes = f"{inherited_classes}, "
|
|
180
|
+
return inheritance_import, inherited_classes
|
|
181
|
+
|
|
182
|
+
def __get_fkeys(repo, class_name, module_path):
|
|
183
|
+
try:
|
|
184
|
+
mod_path = module_path.replace(repo.base_dir, '').replace(os.path.sep, '.')[1:-3]
|
|
185
|
+
mod = importlib.import_module(mod_path)
|
|
186
|
+
importlib.reload(mod)
|
|
187
|
+
cls = mod.__dict__[class_name]
|
|
188
|
+
fkeys = cls.__dict__.get('Fkeys', {})
|
|
189
|
+
return fkeys
|
|
190
|
+
except ModuleNotFoundError:
|
|
191
|
+
pass
|
|
192
|
+
return {}
|
|
193
|
+
|
|
194
|
+
def __assemble_module_template(module_path):
|
|
195
|
+
"""Construct the module after slicing it if it already exists.
|
|
196
|
+
"""
|
|
197
|
+
ALT_BEGIN_CODE = "#>>> PLACE YOUR CODE BELLOW THIS LINE. DO NOT REMOVE THIS LINE!\n"
|
|
198
|
+
user_s_code = ""
|
|
199
|
+
global_user_s_code = "\n"
|
|
200
|
+
module_template = MODULE_FORMAT
|
|
201
|
+
user_s_class_attr = ''
|
|
202
|
+
if os.path.exists(module_path):
|
|
203
|
+
module_code = utils.read(module_path)
|
|
204
|
+
if module_code.find(ALT_BEGIN_CODE) != -1:
|
|
205
|
+
module_code = module_code.replace(ALT_BEGIN_CODE, utils.BEGIN_CODE)
|
|
206
|
+
user_s_code = module_code.rsplit(utils.BEGIN_CODE, 1)[1]
|
|
207
|
+
user_s_code = user_s_code.replace('{', '{{').replace('}', '}}')
|
|
208
|
+
global_user_s_code = module_code.rsplit(utils.END_CODE)[0].split(utils.BEGIN_CODE)[1]
|
|
209
|
+
global_user_s_code = global_user_s_code.replace('{', '{{').replace('}', '}}')
|
|
210
|
+
user_s_class_attr = module_code.split(utils.BEGIN_CODE)[2].split(f' {utils.END_CODE}')[0]
|
|
211
|
+
user_s_class_attr = user_s_class_attr.replace('{', '{{').replace('}', '}}')
|
|
212
|
+
return module_template.format(
|
|
213
|
+
rt1=MODULE_TEMPLATE_1, rt2=MODULE_TEMPLATE_2, rt3=MODULE_TEMPLATE_3,
|
|
214
|
+
bc_=utils.BEGIN_CODE, ec_=utils.END_CODE,
|
|
215
|
+
global_user_s_code=global_user_s_code,
|
|
216
|
+
user_s_class_attr=user_s_class_attr,
|
|
217
|
+
user_s_code=user_s_code)
|
|
218
|
+
|
|
219
|
+
def __update_this_module(
|
|
220
|
+
repo, relation, package_dir, package_name):
|
|
221
|
+
"""Updates the module."""
|
|
222
|
+
_, fqtn = relation
|
|
223
|
+
path = list(fqtn)
|
|
224
|
+
if path[1].find('half_orm_meta') == 0:
|
|
225
|
+
# hop internal. do nothing
|
|
226
|
+
return None
|
|
227
|
+
fqtn = '.'.join(path[1:])
|
|
228
|
+
try:
|
|
229
|
+
rel = repo.database.model.get_relation_class(fqtn)()
|
|
230
|
+
except (TypeError, UnknownRelation) as err:
|
|
231
|
+
sys.stderr.write(f"{err}\n{fqtn}\n")
|
|
232
|
+
sys.stderr.flush()
|
|
233
|
+
return None
|
|
234
|
+
fields = []
|
|
235
|
+
kwargs = []
|
|
236
|
+
arg_names = []
|
|
237
|
+
for key, value in rel._ho_fields.items():
|
|
238
|
+
error = utils.check_attribute_name(key)
|
|
239
|
+
if not error:
|
|
240
|
+
fields.append(f"self.{key}: Field = None")
|
|
241
|
+
kwarg_type = 'typing.Any'
|
|
242
|
+
if hasattr(value.py_type, '__name__'):
|
|
243
|
+
kwarg_type = str(value.py_type.__name__)
|
|
244
|
+
kwargs.append(f"{key}: '{kwarg_type}'=None")
|
|
245
|
+
arg_names.append(f'{key}={key}')
|
|
246
|
+
fields = "\n ".join(fields)
|
|
247
|
+
kwargs.append('**kwargs')
|
|
248
|
+
kwargs = ", ".join(kwargs)
|
|
249
|
+
arg_names = ", ".join(arg_names)
|
|
250
|
+
path[0] = package_dir
|
|
251
|
+
path[1] = path[1].replace('.', os.sep)
|
|
252
|
+
|
|
253
|
+
path = [iskeyword(elt) and f'{elt}_' or elt for elt in path]
|
|
254
|
+
class_name = camel_case(path[-1])
|
|
255
|
+
module_path = f"{os.path.join(*path)}.py"
|
|
256
|
+
path_1 = os.path.join(*path[:-1])
|
|
257
|
+
if not os.path.exists(path_1):
|
|
258
|
+
os.makedirs(path_1)
|
|
259
|
+
module_template = __assemble_module_template(module_path)
|
|
260
|
+
inheritance_import, inherited_classes = __get_inheritance_info(
|
|
261
|
+
rel, package_name)
|
|
262
|
+
with open(module_path, 'w', encoding='utf-8') as file_:
|
|
263
|
+
documentation = "\n".join([line and f" {line}" or "" for line in str(rel).split("\n")])
|
|
264
|
+
file_.write(
|
|
265
|
+
module_template.format(
|
|
266
|
+
hop_release = hop_version(),
|
|
267
|
+
module=f"{package_name}.{fqtn}",
|
|
268
|
+
package_name=package_name,
|
|
269
|
+
documentation=documentation,
|
|
270
|
+
inheritance_import=inheritance_import,
|
|
271
|
+
inherited_classes=inherited_classes,
|
|
272
|
+
class_name=class_name,
|
|
273
|
+
dc_name=rel._ho_dataclass_name(),
|
|
274
|
+
fqtn=fqtn,
|
|
275
|
+
kwargs=kwargs,
|
|
276
|
+
arg_names=arg_names,
|
|
277
|
+
warning=WARNING_TEMPLATE.format(package_name=package_name)))
|
|
278
|
+
if not os.path.exists(module_path.replace('.py', TEST_EXT)):
|
|
279
|
+
with open(module_path.replace('.py', TEST_EXT), 'w', encoding='utf-8') as file_:
|
|
280
|
+
file_.write(TEST.format(
|
|
281
|
+
BEGIN_CODE=utils.BEGIN_CODE,
|
|
282
|
+
END_CODE=utils.END_CODE,
|
|
283
|
+
package_name=package_name,
|
|
284
|
+
module=f"{package_name}.{fqtn}",
|
|
285
|
+
class_name=camel_case(path[-1]))
|
|
286
|
+
)
|
|
287
|
+
HO_DATACLASSES.append(__gen_dataclass(
|
|
288
|
+
rel, __get_fkeys(repo, class_name, module_path)))
|
|
289
|
+
return module_path
|
|
290
|
+
|
|
291
|
+
def __reset_dataclasses(repo, package_dir):
|
|
292
|
+
with open(os.path.join(package_dir, "ho_dataclasses.py"), "w", encoding='utf-8') as file_:
|
|
293
|
+
for relation in repo.database.model._relations():
|
|
294
|
+
t_qrn = relation[1][1:]
|
|
295
|
+
if t_qrn[0].find('half_orm') == 0:
|
|
296
|
+
continue
|
|
297
|
+
file_.write(f'class DC_{__get_full_class_name(*t_qrn)}: ...\n')
|
|
298
|
+
|
|
299
|
+
def __gen_dataclasses(package_dir, package_name):
|
|
300
|
+
with open(os.path.join(package_dir, "ho_dataclasses.py"), "w", encoding='utf-8') as file_:
|
|
301
|
+
file_.write(f"# dataclasses for {package_name}\n\n")
|
|
302
|
+
hd_imports = list(HO_DATACLASSES_IMPORTS)
|
|
303
|
+
hd_imports.sort()
|
|
304
|
+
for to_import in hd_imports:
|
|
305
|
+
file_.write(f"import {to_import}\n")
|
|
306
|
+
file_.write("\n")
|
|
307
|
+
for dc in HO_DATACLASSES:
|
|
308
|
+
file_.write(f"\n{dc}\n")
|
|
309
|
+
|
|
310
|
+
def generate(repo):
|
|
311
|
+
"""Synchronize the modules with the structure of the relation in PG.
|
|
312
|
+
"""
|
|
313
|
+
package_name = repo.name
|
|
314
|
+
package_dir = os.path.join(repo.base_dir, package_name)
|
|
315
|
+
files_list = []
|
|
316
|
+
try:
|
|
317
|
+
sql_adapter_module = importlib.import_module('.sql_adapter', package_name)
|
|
318
|
+
SQL_ADAPTER.update(sql_adapter_module.SQL_ADAPTER)
|
|
319
|
+
except ModuleNotFoundError as exc:
|
|
320
|
+
os.makedirs(package_dir)
|
|
321
|
+
with open(os.path.join(package_dir, 'sql_adapter.py'), "w") as file_:
|
|
322
|
+
file_.write(SQL_ADAPTER_TEMPLATE)
|
|
323
|
+
sys.stderr.write(f"{exc}\n")
|
|
324
|
+
except AttributeError as exc:
|
|
325
|
+
sys.stderr.write(f"{exc}\n")
|
|
326
|
+
repo.database.model._reload()
|
|
327
|
+
if not os.path.exists(package_dir):
|
|
328
|
+
os.mkdir(package_dir)
|
|
329
|
+
|
|
330
|
+
__reset_dataclasses(repo, package_dir)
|
|
331
|
+
|
|
332
|
+
with open(os.path.join(package_dir, INIT_PY), 'w', encoding='utf-8') as file_:
|
|
333
|
+
file_.write(INIT_MODULE_TEMPLATE.format(package_name=package_name))
|
|
334
|
+
|
|
335
|
+
if not os.path.exists(os.path.join(package_dir, BASE_TEST_PY)):
|
|
336
|
+
with open(os.path.join(package_dir, BASE_TEST_PY), 'w', encoding='utf-8') as file_:
|
|
337
|
+
file_.write(BASE_TEST.format(
|
|
338
|
+
BEGIN_CODE=utils.BEGIN_CODE,
|
|
339
|
+
END_CODE=utils.END_CODE,
|
|
340
|
+
package_name=package_name))
|
|
341
|
+
warning = WARNING_TEMPLATE.format(package_name=package_name)
|
|
342
|
+
for relation in repo.database.model._relations():
|
|
343
|
+
module_path = __update_this_module(repo, relation, package_dir, package_name)
|
|
344
|
+
if module_path:
|
|
345
|
+
files_list.append(module_path)
|
|
346
|
+
if module_path.find(INIT_PY) == -1:
|
|
347
|
+
test_file_path = module_path.replace('.py', TEST_EXT)
|
|
348
|
+
files_list.append(test_file_path)
|
|
349
|
+
|
|
350
|
+
__gen_dataclasses(package_dir, package_name)
|
|
351
|
+
|
|
352
|
+
if len(NO_APAPTER):
|
|
353
|
+
print("MISSING ADAPTER FOR SQL TYPE")
|
|
354
|
+
print(f"Add the following items to __SQL_ADAPTER in {os.path.join(package_dir, 'sql_adapter.py')}")
|
|
355
|
+
for key in NO_APAPTER.keys():
|
|
356
|
+
print(f" '{key}': typing.Any,")
|
|
357
|
+
__update_init_files(package_dir, files_list, warning)
|