pychestrate-core 0.0.1__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.
- ccai/pychestrate/core/__init__.py +0 -0
- ccai/pychestrate/core/examples/create_database.py +52 -0
- ccai/pychestrate/core/storage/__init__.py +0 -0
- ccai/pychestrate/core/storage/core/__init__.py +0 -0
- ccai/pychestrate/core/storage/dbconnection.py +269 -0
- ccai/pychestrate/core/storage/dbio.py +158 -0
- ccai/pychestrate/core/storage/defaults.py +29 -0
- ccai/pychestrate/core/storage/orm.py +725 -0
- pychestrate_core-0.0.1.dist-info/METADATA +53 -0
- pychestrate_core-0.0.1.dist-info/RECORD +12 -0
- pychestrate_core-0.0.1.dist-info/WHEEL +4 -0
- pychestrate_core-0.0.1.dist-info/licenses/LICENSE.md +204 -0
|
File without changes
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
|
|
2
|
+
__author__ = "Myron Walker"
|
|
3
|
+
__copyright__ = "Copyright 2025, Automation Mojo LLC"
|
|
4
|
+
__credits__ = []
|
|
5
|
+
__version__ = "1.0.0"
|
|
6
|
+
|
|
7
|
+
from ccai.runtime.activation import activate_runtime, ActivationProfile
|
|
8
|
+
|
|
9
|
+
from ccai.configuration.configurationmaps import resolve_configuration_maps
|
|
10
|
+
from ccai.configuration.configurationsettings import establish_configuration_settings
|
|
11
|
+
from ccai.configuration.configurationvariables import resolve_configuration_variables
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
from ccai.credentials.wellknown import CredentialManagerSingleton
|
|
15
|
+
|
|
16
|
+
from ccai.dataprofiles.wellknown import DataProfileManagerSingleton
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
from ccai.pychestrate.core.storage.dbconnection import create_database_connection_factory
|
|
20
|
+
from ccai.pychestrate.core.storage.dbio import database_exists, database_create
|
|
21
|
+
from ccai.pychestrate.core.storage.orm import PychestrateModelBase
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def create_database_main():
|
|
25
|
+
|
|
26
|
+
establish_configuration_settings(name="pychestrate", presence_dir="~/pychestrate")
|
|
27
|
+
|
|
28
|
+
resolve_configuration_variables()
|
|
29
|
+
|
|
30
|
+
activate_runtime(profile=ActivationProfile.Command)
|
|
31
|
+
|
|
32
|
+
resolve_configuration_maps(use_credentials=True, use_landscape=True)
|
|
33
|
+
|
|
34
|
+
profile_manager = DataProfileManagerSingleton()
|
|
35
|
+
dbprofile = profile_manager.lookup_profile("software-pipeline-admin")
|
|
36
|
+
|
|
37
|
+
cred_manager = CredentialManagerSingleton()
|
|
38
|
+
|
|
39
|
+
dbfactory = create_database_connection_factory(dbprofile=dbprofile, cred_manager=cred_manager)
|
|
40
|
+
|
|
41
|
+
dbname = "pipeline"
|
|
42
|
+
|
|
43
|
+
if not database_exists(dbfactory, dbname):
|
|
44
|
+
database_create(dbfactory, dbname=dbname, dbmetadata=PychestrateModelBase.metadata)
|
|
45
|
+
|
|
46
|
+
return
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
if __name__ == "__main__":
|
|
50
|
+
|
|
51
|
+
create_database_main()
|
|
52
|
+
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
"""
|
|
2
|
+
.. module:: dbconnection
|
|
3
|
+
:platform: Darwin, Linux, Unix, Windows
|
|
4
|
+
:synopsis: Contains helper functions for working with specific databases
|
|
5
|
+
|
|
6
|
+
.. moduleauthor:: Myron Walker <myron.walker@gmail.com>
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
__author__ = "Myron Walker"
|
|
10
|
+
__copyright__ = "Copyright 2025, Automation Mojo LLC"
|
|
11
|
+
__credits__ = []
|
|
12
|
+
__version__ = "1.0.0"
|
|
13
|
+
|
|
14
|
+
from typing import Optional
|
|
15
|
+
|
|
16
|
+
import logging
|
|
17
|
+
import os
|
|
18
|
+
|
|
19
|
+
from sqlalchemy import create_engine
|
|
20
|
+
from sqlalchemy.engine.base import Engine as SqlEngine
|
|
21
|
+
|
|
22
|
+
from ccai.errors.exceptions import ConfigurationError
|
|
23
|
+
|
|
24
|
+
from ccai.credentials.basecredential import BaseCredential
|
|
25
|
+
from ccai.credentials.basiccredential import BasicCredential
|
|
26
|
+
from ccai.credentials.credentialmanager import CredentialManager
|
|
27
|
+
|
|
28
|
+
from ccai.dataprofiles.databasebasicsocketprofile import DatabaseBasicSocketProfile
|
|
29
|
+
from ccai.dataprofiles.databasebasictcpprofile import DatabaseBasicTcpProfile
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
logger = logging.getLogger()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class DatabaseConnectionFactory:
|
|
36
|
+
|
|
37
|
+
def __init__(self, profile_name: str, *, dbprofile: DatabaseBasicSocketProfile, credential: BaseCredential):
|
|
38
|
+
self._profile_name = profile_name
|
|
39
|
+
self._dbprofile = dbprofile
|
|
40
|
+
self._credential = credential
|
|
41
|
+
return
|
|
42
|
+
|
|
43
|
+
@property
|
|
44
|
+
def credential(self) -> BaseCredential:
|
|
45
|
+
return self._credential
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def dbprofile(self) -> DatabaseBasicSocketProfile:
|
|
49
|
+
return self._dbprofile
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
def profile_name(self) -> str:
|
|
53
|
+
return self._profile_name
|
|
54
|
+
|
|
55
|
+
def create_engine(self, *, dbname=None, echo=True) -> SqlEngine:
|
|
56
|
+
errmsg = "The 'create_engine' method must be overloaded by 'DatabaseConnectionFactory' derived types."
|
|
57
|
+
raise NotImplementedError(errmsg)
|
|
58
|
+
|
|
59
|
+
def format_connection_string() -> str:
|
|
60
|
+
errmsg = "The 'format_connection_string' method must be overloaded by 'DatabaseConnectionFactory' derived types."
|
|
61
|
+
raise NotImplementedError(errmsg)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class BasicSocketDatabaseConnectionFactory(DatabaseConnectionFactory):
|
|
65
|
+
|
|
66
|
+
def __init__(self, profile_name: str, *, dbprofile: DatabaseBasicSocketProfile, credential: BaseCredential):
|
|
67
|
+
super().__init__(profile_name, dbprofile=dbprofile, credential=credential)
|
|
68
|
+
return
|
|
69
|
+
|
|
70
|
+
def create_engine(self, *, dbname=None, echo=True) -> SqlEngine:
|
|
71
|
+
"""Create a SQLAlchemy engine using pipe based connectivity."""
|
|
72
|
+
|
|
73
|
+
socket_path: str = self.dbprofile.socket
|
|
74
|
+
|
|
75
|
+
if dbname is None and self.dbprofile.dbname is not None:
|
|
76
|
+
dbname = self.dbprofile.dbname
|
|
77
|
+
|
|
78
|
+
if dbname is None:
|
|
79
|
+
warnmsg = "BasicSocketDatabaseConnectionFactory.create_engine: dbname was None."
|
|
80
|
+
logger.warn(warnmsg)
|
|
81
|
+
|
|
82
|
+
if isinstance(self.credential, BasicCredential):
|
|
83
|
+
connstr = self.format_connection_string(dbname=dbname)
|
|
84
|
+
dbengine = create_engine(connstr, echo=echo)
|
|
85
|
+
else:
|
|
86
|
+
errmsg = (
|
|
87
|
+
"BasicSocketDatabaseConnectionFactory requires a BasicCredential to "
|
|
88
|
+
"create an engine."
|
|
89
|
+
)
|
|
90
|
+
raise ConfigurationError(errmsg)
|
|
91
|
+
|
|
92
|
+
return dbengine
|
|
93
|
+
|
|
94
|
+
def get_connection_scheme(self):
|
|
95
|
+
"""Return the SQLAlchemy connection scheme for the profile."""
|
|
96
|
+
|
|
97
|
+
conn_scheme = None
|
|
98
|
+
|
|
99
|
+
if self.dbprofile.dbtype == "postgresql":
|
|
100
|
+
try:
|
|
101
|
+
import psycopg2 # noqa: F401
|
|
102
|
+
except ImportError:
|
|
103
|
+
errmsg_lines = [
|
|
104
|
+
"In order to create a postgresql database engine, you must install the following dependencies.",
|
|
105
|
+
"DEPENDENCIES",
|
|
106
|
+
" psycopg2",
|
|
107
|
+
]
|
|
108
|
+
errmsg = os.linesep.join(errmsg_lines)
|
|
109
|
+
raise ConfigurationError(errmsg)
|
|
110
|
+
|
|
111
|
+
conn_scheme = "postgresql+psycopg2"
|
|
112
|
+
|
|
113
|
+
return conn_scheme
|
|
114
|
+
|
|
115
|
+
def format_connection_string(self, dbname: Optional[str] = None) -> str:
|
|
116
|
+
"""Build a connection string for pipe based access."""
|
|
117
|
+
|
|
118
|
+
conn_scheme: str = self.get_connection_scheme()
|
|
119
|
+
|
|
120
|
+
socket_path: str = self.dbprofile.socket
|
|
121
|
+
|
|
122
|
+
if not isinstance(self.credential, BasicCredential):
|
|
123
|
+
errmsg = (
|
|
124
|
+
"BasicSocketDatabaseConnectionFactory requires a BasicCredential to "
|
|
125
|
+
"format the connection string."
|
|
126
|
+
)
|
|
127
|
+
raise ConfigurationError(errmsg)
|
|
128
|
+
|
|
129
|
+
credobj: BasicCredential = self.credential
|
|
130
|
+
|
|
131
|
+
username = credobj.username
|
|
132
|
+
password = credobj.password
|
|
133
|
+
|
|
134
|
+
if dbname is None:
|
|
135
|
+
dbname = self.dbprofile.dbname
|
|
136
|
+
|
|
137
|
+
conn_str = f"{conn_scheme}://{username}:{password}@/{dbname}?host={socket_path}"
|
|
138
|
+
|
|
139
|
+
return conn_str
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
class BasicTcpDatabaseConnectionFactory(DatabaseConnectionFactory):
|
|
143
|
+
|
|
144
|
+
def __init__(self, profile_name: str, *, dbprofile: DatabaseBasicTcpProfile, credential: BaseCredential):
|
|
145
|
+
super().__init__(profile_name, dbprofile=dbprofile, credential=credential)
|
|
146
|
+
return
|
|
147
|
+
|
|
148
|
+
@property
|
|
149
|
+
def dbprofile(self) -> DatabaseBasicTcpProfile:
|
|
150
|
+
return self._dbprofile
|
|
151
|
+
|
|
152
|
+
def create_engine(self, *, dbname=None, echo=True) -> SqlEngine:
|
|
153
|
+
|
|
154
|
+
conn_scheme = None
|
|
155
|
+
|
|
156
|
+
# If the database type we are creating an engine for is postgresql, make sure
|
|
157
|
+
# we can import all of the postgresql dependencies.
|
|
158
|
+
if self.dbprofile.dbtype == 'postgresql':
|
|
159
|
+
try:
|
|
160
|
+
import psycopg2
|
|
161
|
+
except ImportError:
|
|
162
|
+
errmsg_lines = [
|
|
163
|
+
"In order to create a postgresql database engine, you must install the following dependencies.",
|
|
164
|
+
"DEPENDENCIES",
|
|
165
|
+
" psycopg2"
|
|
166
|
+
]
|
|
167
|
+
errmsg = os.linesep.join(errmsg_lines)
|
|
168
|
+
raise ConfigurationError(errmsg)
|
|
169
|
+
|
|
170
|
+
conn_scheme = "postgresql+psycopg2"
|
|
171
|
+
|
|
172
|
+
if dbname is None and self.dbprofile.dbname is not None:
|
|
173
|
+
dbname = self.dbprofile.dbname
|
|
174
|
+
|
|
175
|
+
if dbname is None:
|
|
176
|
+
warnmsg = "BasicTcpDatabaseConnectionFactory.create_engine: dbname was None."
|
|
177
|
+
logger.warn(warnmsg)
|
|
178
|
+
|
|
179
|
+
if isinstance(self.credential, BasicCredential):
|
|
180
|
+
credobj: BasicCredential = self.credential
|
|
181
|
+
|
|
182
|
+
passwd = credobj.password
|
|
183
|
+
|
|
184
|
+
connstr = self.format_connection_string(dbname=dbname)
|
|
185
|
+
|
|
186
|
+
dbengine = create_engine(connstr, echo=echo)
|
|
187
|
+
|
|
188
|
+
return dbengine
|
|
189
|
+
|
|
190
|
+
def get_connection_scheme(self):
|
|
191
|
+
|
|
192
|
+
conn_scheme = None
|
|
193
|
+
|
|
194
|
+
# If the database type we are creating an engine for is postgresql, make sure
|
|
195
|
+
# we can import all of the postgresql dependencies.
|
|
196
|
+
if self.dbprofile.dbtype == 'postgresql':
|
|
197
|
+
try:
|
|
198
|
+
import psycopg2
|
|
199
|
+
except ImportError:
|
|
200
|
+
errmsg_lines = [
|
|
201
|
+
"In order to create a postgresql database engine, you must install the following dependencies.",
|
|
202
|
+
"DEPENDENCIES",
|
|
203
|
+
" psycopg2"
|
|
204
|
+
]
|
|
205
|
+
errmsg = os.linesep.join(errmsg_lines)
|
|
206
|
+
raise ConfigurationError(errmsg)
|
|
207
|
+
|
|
208
|
+
conn_scheme = "postgresql+psycopg2"
|
|
209
|
+
|
|
210
|
+
return conn_scheme
|
|
211
|
+
|
|
212
|
+
def format_connection_string(self, dbname: Optional[str]=None) -> str:
|
|
213
|
+
|
|
214
|
+
conn_str = None
|
|
215
|
+
|
|
216
|
+
conn_scheme: str = self.get_connection_scheme()
|
|
217
|
+
host: str = self.dbprofile.host
|
|
218
|
+
port: str = self.dbprofile.port
|
|
219
|
+
|
|
220
|
+
if isinstance(self.credential, BasicCredential):
|
|
221
|
+
credobj: BasicCredential = self.credential
|
|
222
|
+
|
|
223
|
+
username = credobj.username
|
|
224
|
+
password = credobj.password
|
|
225
|
+
|
|
226
|
+
conn_str = f"{conn_scheme}://{username}:{password}@{host}:{port}"
|
|
227
|
+
|
|
228
|
+
if dbname is not None:
|
|
229
|
+
conn_str += f"/{dbname}"
|
|
230
|
+
else:
|
|
231
|
+
conn_str += f"/{self.dbprofile.dbname}"
|
|
232
|
+
|
|
233
|
+
return conn_str
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
DATABASE_CONNECTION_FACTORIES = {}
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
def create_database_connection_factory(dbprofile: DatabaseBasicSocketProfile, cred_manager: CredentialManager) -> DatabaseConnectionFactory:
|
|
241
|
+
|
|
242
|
+
global DATABASE_CONNECTION_FACTORIES
|
|
243
|
+
|
|
244
|
+
conn_factory = None
|
|
245
|
+
|
|
246
|
+
profile_name = dbprofile.identifier
|
|
247
|
+
|
|
248
|
+
if profile_name in DATABASE_CONNECTION_FACTORIES:
|
|
249
|
+
conn_factory = DATABASE_CONNECTION_FACTORIES[profile_name]
|
|
250
|
+
|
|
251
|
+
else:
|
|
252
|
+
|
|
253
|
+
credential_name = dbprofile.credential
|
|
254
|
+
|
|
255
|
+
credential: BaseCredential = cred_manager.credentials[credential_name]
|
|
256
|
+
|
|
257
|
+
category = dbprofile.category
|
|
258
|
+
if category == "basic-socket":
|
|
259
|
+
conn_factory = BasicSocketDatabaseConnectionFactory(profile_name, dbprofile=dbprofile, credential=credential)
|
|
260
|
+
elif category == "basic-tcp":
|
|
261
|
+
conn_factory = BasicTcpDatabaseConnectionFactory(profile_name, dbprofile=dbprofile, credential=credential)
|
|
262
|
+
else:
|
|
263
|
+
errmsg = "Unknown database connection type. profile_name={} category={}".format(
|
|
264
|
+
profile_name, category)
|
|
265
|
+
raise ConfigurationError(errmsg)
|
|
266
|
+
|
|
267
|
+
DATABASE_CONNECTION_FACTORIES[profile_name] = conn_factory
|
|
268
|
+
|
|
269
|
+
return conn_factory
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"""
|
|
2
|
+
.. module:: dbio
|
|
3
|
+
:platform: Darwin, Linux, Unix, Windows
|
|
4
|
+
:synopsis: Contains helper functions for working with specific databases
|
|
5
|
+
|
|
6
|
+
.. moduleauthor:: Myron Walker <myron.walker@gmail.com>
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
__author__ = "Myron Walker"
|
|
10
|
+
__copyright__ = "Copyright 2025, Automation Mojo LLC"
|
|
11
|
+
__credits__ = []
|
|
12
|
+
__version__ = "1.0.0"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
from typing import Optional
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
import contextlib
|
|
19
|
+
import logging
|
|
20
|
+
|
|
21
|
+
from sqlalchemy.engine.base import Engine as SqlEngine
|
|
22
|
+
from sqlalchemy.sql.schema import MetaData
|
|
23
|
+
|
|
24
|
+
from sqlalchemy_utils import database_exists as sqlutils_database_exists
|
|
25
|
+
from sqlalchemy_utils import create_database as sqlutils_create_database
|
|
26
|
+
from sqlalchemy_utils import drop_database as sqlutils_drop_database
|
|
27
|
+
|
|
28
|
+
from ccai.errors.exceptions import ConfigurationError
|
|
29
|
+
|
|
30
|
+
from ccai.credentials.credentialmanager import CredentialManager
|
|
31
|
+
|
|
32
|
+
from ccai.dataprofiles.databasebasicsocketprofile import DatabaseBasicSocketProfile
|
|
33
|
+
|
|
34
|
+
from ccai.pychestrate.core.storage.orm import PychestrateModelBase
|
|
35
|
+
|
|
36
|
+
from ccai.pychestrate.core.storage.dbconnection import DatabaseConnectionFactory, create_database_connection_factory
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
logger = logging.getLogger()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def database_exists(conn_factory: DatabaseConnectionFactory, dbname: Optional[str]=None) -> bool:
|
|
43
|
+
"""
|
|
44
|
+
Checks to see if the specified database exists.
|
|
45
|
+
"""
|
|
46
|
+
conn_str = conn_factory.format_connection_string(dbname=dbname)
|
|
47
|
+
|
|
48
|
+
exists = sqlutils_database_exists(conn_str)
|
|
49
|
+
|
|
50
|
+
return exists
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def database_create(conn_factory: DatabaseConnectionFactory, dbname: Optional[str]=None, dbmetadata: Optional[MetaData]=None):
|
|
54
|
+
"""
|
|
55
|
+
Creates the specified database.
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
conn_str = conn_factory.format_connection_string(dbname=dbname)
|
|
59
|
+
|
|
60
|
+
sqlutils_create_database(conn_str)
|
|
61
|
+
|
|
62
|
+
if dbmetadata is not None:
|
|
63
|
+
engine = conn_factory.create_engine(dbname=dbname)
|
|
64
|
+
dbmetadata.create_all(engine)
|
|
65
|
+
|
|
66
|
+
return
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def create_network_attached_database(db_profile: DatabaseBasicSocketProfile, cred_manager: CredentialManager, orm_metadata: MetaData, *, reset: bool = False):
|
|
70
|
+
"""
|
|
71
|
+
Creates the 'pychestrate' database.
|
|
72
|
+
|
|
73
|
+
:param db_profile: The database profile configuration.
|
|
74
|
+
:param cred_manager: Credential manager instance for obtaining credentials.
|
|
75
|
+
:param orm_metadata: The Object Relational Model to use when creating the database.
|
|
76
|
+
:param reset: When ``True`` delete the existing database before creation.
|
|
77
|
+
"""
|
|
78
|
+
db_name = db_profile.dbname
|
|
79
|
+
|
|
80
|
+
conn_factory = create_database_connection_factory(db_profile, cred_manager)
|
|
81
|
+
if conn_factory is None:
|
|
82
|
+
db_profile_name = db_profile["name"]
|
|
83
|
+
errmsg = "'create_network_attached_database' could not get a connection factory for profile={}".format(
|
|
84
|
+
db_profile_name
|
|
85
|
+
)
|
|
86
|
+
raise ConfigurationError(errmsg)
|
|
87
|
+
|
|
88
|
+
if reset and database_exists(conn_factory, db_name):
|
|
89
|
+
conn_str = conn_factory.format_connection_string(dbname=db_name)
|
|
90
|
+
sqlutils_drop_database(conn_str)
|
|
91
|
+
|
|
92
|
+
if not database_exists(conn_factory, db_name):
|
|
93
|
+
database_create(conn_factory, db_name)
|
|
94
|
+
|
|
95
|
+
engine = conn_factory.create_engine(dbname=db_name, echo=True)
|
|
96
|
+
|
|
97
|
+
orm_metadata.create_all(engine, checkfirst=True)
|
|
98
|
+
|
|
99
|
+
return
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def open_network_attached_database(db_profile: DatabaseBasicSocketProfile, cred_manager: CredentialManager) -> SqlEngine:
|
|
103
|
+
"""
|
|
104
|
+
Opens the postgresql database.
|
|
105
|
+
|
|
106
|
+
:param db_profile: The database profile configuration.
|
|
107
|
+
:param cred_manager: Credential manager instance for obtaining credentials.
|
|
108
|
+
:param orm_metadata: The Object Relational Model to use when creating the database.
|
|
109
|
+
:param reset: When ``True`` delete the existing database before creation.
|
|
110
|
+
|
|
111
|
+
:returns: A :class:`SqlEngine` object that can be used to interoperate with the specified database.
|
|
112
|
+
"""
|
|
113
|
+
dbname = db_profile.dbname
|
|
114
|
+
|
|
115
|
+
conn_factory = create_database_connection_factory(db_profile, cred_manager)
|
|
116
|
+
if conn_factory is None:
|
|
117
|
+
db_profile_name = db_profile["name"]
|
|
118
|
+
errmsg = "'open_pychestrate_database' could not get a connection factory for profile={}".format(
|
|
119
|
+
db_profile_name
|
|
120
|
+
)
|
|
121
|
+
raise ConfigurationError(errmsg)
|
|
122
|
+
|
|
123
|
+
engine = conn_factory.create_engine(dbname=dbname, echo=True)
|
|
124
|
+
|
|
125
|
+
return engine
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def reset_network_attached_database(db_profile: DatabaseBasicSocketProfile, cred_manager: CredentialManager, orm_metadata: MetaData):
|
|
129
|
+
"""
|
|
130
|
+
Reset a network attached database database.
|
|
131
|
+
|
|
132
|
+
:param db_profile: The database profile configuration.
|
|
133
|
+
:param cred_manager: Credential manager instance for obtaining credentials.
|
|
134
|
+
:param orm_metadata: The Object Relational Model to use when creating the database.
|
|
135
|
+
:param reset: When ``True`` delete the existing database before creation.
|
|
136
|
+
"""
|
|
137
|
+
dbname = db_profile.dbname
|
|
138
|
+
|
|
139
|
+
conn_factory = create_database_connection_factory(db_profile, cred_manager)
|
|
140
|
+
if conn_factory is None:
|
|
141
|
+
db_profile_name = db_profile["name"]
|
|
142
|
+
errmsg = "'reset_pychestrate_database' could not get a connection factory for profile={}".format(
|
|
143
|
+
db_profile_name
|
|
144
|
+
)
|
|
145
|
+
raise ConfigurationError(errmsg)
|
|
146
|
+
|
|
147
|
+
if database_exists(conn_factory, dbname):
|
|
148
|
+
|
|
149
|
+
engine = conn_factory.create_engine(dbname=dbname, echo=True)
|
|
150
|
+
|
|
151
|
+
with contextlib.closing(engine.connect()) as con:
|
|
152
|
+
trans = con.begin()
|
|
153
|
+
con.execute('TRUNCATE {} RESTART IDENTITY;'.format(
|
|
154
|
+
','.join(table.name
|
|
155
|
+
for table in reversed(orm_metadata.sorted_tables))))
|
|
156
|
+
trans.commit()
|
|
157
|
+
|
|
158
|
+
return
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
__author__ = "Myron Walker"
|
|
2
|
+
__copyright__ = "Copyright 2025, Automation Mojo LLC"
|
|
3
|
+
__credits__ = []
|
|
4
|
+
|
|
5
|
+
from uuid import uuid4
|
|
6
|
+
|
|
7
|
+
from datetime import datetime, timezone, timedelta
|
|
8
|
+
|
|
9
|
+
def new_uuid() -> str:
|
|
10
|
+
rtnval = str(uuid4())
|
|
11
|
+
return rtnval
|
|
12
|
+
|
|
13
|
+
def utc_now() -> datetime:
|
|
14
|
+
"""
|
|
15
|
+
Provides the current UTC time. This is used as a default value for datetime fields in models.
|
|
16
|
+
|
|
17
|
+
:return: datetime
|
|
18
|
+
"""
|
|
19
|
+
now = datetime.now(timezone.utc)
|
|
20
|
+
return now
|
|
21
|
+
|
|
22
|
+
def reset_token_expiration() -> datetime:
|
|
23
|
+
"""
|
|
24
|
+
Provides the expiration time for reset tokens. This is set to 24 hours from now.
|
|
25
|
+
|
|
26
|
+
:return: datetime
|
|
27
|
+
"""
|
|
28
|
+
expiration = utc_now() + timedelta(days=1)
|
|
29
|
+
return expiration
|