amsdal 0.3.0__cp310-cp310-macosx_10_9_universal2.whl → 0.3.2__cp310-cp310-macosx_10_9_universal2.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.
Potentially problematic release.
This version of amsdal might be problematic. Click here for more details.
- amsdal/__about__.py +1 -1
- amsdal/cloud/__init__.cpython-310-darwin.so +0 -0
- amsdal/cloud/client.cpython-310-darwin.so +0 -0
- amsdal/cloud/constants.cpython-310-darwin.so +0 -0
- amsdal/cloud/enums.cpython-310-darwin.so +0 -0
- amsdal/cloud/models/__init__.cpython-310-darwin.so +0 -0
- amsdal/cloud/models/base.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/__init__.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/actions/__init__.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/actions/add_allowlist_ip.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/actions/add_basic_auth.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/actions/add_dependency.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/actions/add_secret.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/actions/base.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/actions/create_deploy.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/actions/create_env.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/actions/create_session.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/actions/delete_allowlist_ip.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/actions/delete_basic_auth.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/actions/delete_dependency.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/actions/delete_env.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/actions/delete_secret.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/actions/destroy_deploy.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/actions/expose_db.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/actions/get_basic_auth_credentials.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/actions/get_monitoring_info.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/actions/list_dependencies.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/actions/list_deploys.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/actions/list_envs.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/actions/list_secrets.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/actions/manager.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/actions/signup_action.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/actions/update_deploy.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/auth/__init__.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/auth/base.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/auth/credentials.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/auth/manager.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/auth/signup_service.cpython-310-darwin.so +0 -0
- amsdal/cloud/services/auth/token.cpython-310-darwin.so +0 -0
- amsdal/contrib/__init__.cpython-310-darwin.so +0 -0
- amsdal/contrib/auth/lifecycle/consumer.py +172 -0
- amsdal/contrib/auth/lifecycle/consumer.pyi +36 -0
- amsdal/contrib/auth/models/login_session/hooks/pre_init.py +14 -10
- amsdal/contrib/frontend_configs/lifecycle/consumer.py +45 -0
- amsdal/contrib/frontend_configs/lifecycle/consumer.pyi +12 -0
- amsdal/fixtures/__init__.cpython-310-darwin.so +0 -0
- amsdal/fixtures/manager.cpython-310-darwin.so +0 -0
- amsdal/fixtures/manager.pyi +102 -0
- amsdal/manager.cpython-310-darwin.so +0 -0
- amsdal/manager.pyi +170 -1
- amsdal/migration/__init__.cpython-310-darwin.so +0 -0
- amsdal/migration/base_migration_schemas.cpython-310-darwin.so +0 -0
- amsdal/migration/data_classes.cpython-310-darwin.so +0 -0
- amsdal/migration/executors/__init__.cpython-310-darwin.so +0 -0
- amsdal/migration/executors/base.cpython-310-darwin.so +0 -0
- amsdal/migration/executors/base.pyi +12 -0
- amsdal/migration/executors/default_executor.cpython-310-darwin.so +0 -0
- amsdal/migration/executors/default_executor.pyi +88 -1
- amsdal/migration/executors/state_executor.cpython-310-darwin.so +0 -0
- amsdal/migration/file_migration_executor.cpython-310-darwin.so +0 -0
- amsdal/migration/file_migration_generator.cpython-310-darwin.so +0 -0
- amsdal/migration/file_migration_store.cpython-310-darwin.so +0 -0
- amsdal/migration/file_migration_writer.cpython-310-darwin.so +0 -0
- amsdal/migration/migrations.cpython-310-darwin.so +0 -0
- amsdal/migration/migrations_loader.cpython-310-darwin.so +0 -0
- amsdal/migration/schemas_loaders.cpython-310-darwin.so +0 -0
- amsdal/migration/utils.cpython-310-darwin.so +0 -0
- amsdal/mixins/__init__.cpython-310-darwin.so +0 -0
- amsdal/mixins/build_mixin.cpython-310-darwin.so +0 -0
- amsdal/mixins/class_versions_mixin.cpython-310-darwin.so +0 -0
- amsdal/mixins/class_versions_mixin.pyi +7 -1
- amsdal/schemas/manager.cpython-310-darwin.so +0 -0
- amsdal/services/__init__.cpython-310-darwin.so +0 -0
- amsdal/services/transaction_execution.cpython-310-darwin.so +0 -0
- amsdal/utils/rollback/__init__.py +195 -0
- amsdal/utils/rollback/__init__.pyi +16 -0
- {amsdal-0.3.0.dist-info → amsdal-0.3.2.dist-info}/METADATA +5 -3
- {amsdal-0.3.0.dist-info → amsdal-0.3.2.dist-info}/RECORD +82 -82
- {amsdal-0.3.0.dist-info → amsdal-0.3.2.dist-info}/LICENSE.txt +0 -0
- {amsdal-0.3.0.dist-info → amsdal-0.3.2.dist-info}/WHEEL +0 -0
- {amsdal-0.3.0.dist-info → amsdal-0.3.2.dist-info}/licenses/LICENSE.txt +0 -0
- {amsdal-0.3.0.dist-info → amsdal-0.3.2.dist-info}/top_level.txt +0 -0
amsdal/manager.pyi
CHANGED
|
@@ -4,7 +4,7 @@ from amsdal.cloud.services.auth.manager import AuthManager as AuthManager
|
|
|
4
4
|
from amsdal.cloud.services.auth.signup_service import SignupService as SignupService
|
|
5
5
|
from amsdal.configs.main import settings as settings
|
|
6
6
|
from amsdal.errors import AmsdalAuthenticationError as AmsdalAuthenticationError, AmsdalMissingCredentialsError as AmsdalMissingCredentialsError, AmsdalRuntimeError as AmsdalRuntimeError, AmsdalSignupError as AmsdalSignupError
|
|
7
|
-
from amsdal.fixtures.manager import FixturesManager as FixturesManager
|
|
7
|
+
from amsdal.fixtures.manager import AsyncFixturesManager as AsyncFixturesManager, FixturesManager as FixturesManager
|
|
8
8
|
from amsdal.mixins.build_mixin import BuildMixin as BuildMixin
|
|
9
9
|
from amsdal.mixins.class_versions_mixin import ClassVersionsMixin as ClassVersionsMixin
|
|
10
10
|
from amsdal.schemas.manager import SchemaManager as SchemaManager
|
|
@@ -181,3 +181,172 @@ class AmsdalManager(BuildMixin, ClassVersionsMixin, metaclass=Singleton):
|
|
|
181
181
|
Returns:
|
|
182
182
|
None
|
|
183
183
|
"""
|
|
184
|
+
|
|
185
|
+
class AsyncAmsdalManager(BuildMixin, ClassVersionsMixin, metaclass=Singleton):
|
|
186
|
+
"""
|
|
187
|
+
Manages the AMSDAL framework components and operations.
|
|
188
|
+
|
|
189
|
+
This class is responsible for initializing, setting up, and managing various components
|
|
190
|
+
of the AMSDAL framework, including connections, data management, schema management,
|
|
191
|
+
and authentication. It also provides methods for building and tearing down the framework.
|
|
192
|
+
"""
|
|
193
|
+
_class_manager: ClassManager
|
|
194
|
+
_config_manager: Incomplete
|
|
195
|
+
_config: Incomplete
|
|
196
|
+
_data_application: Incomplete
|
|
197
|
+
_is_setup: bool
|
|
198
|
+
__is_authenticated: bool
|
|
199
|
+
_schema_manager: Incomplete
|
|
200
|
+
_metadata_manager: Incomplete
|
|
201
|
+
_auth_manager: Incomplete
|
|
202
|
+
def __init__(self, *, raise_on_new_signup: bool = False) -> None:
|
|
203
|
+
"""
|
|
204
|
+
Initializes all sub managers. Reads the configuration.
|
|
205
|
+
|
|
206
|
+
Returns:
|
|
207
|
+
None
|
|
208
|
+
"""
|
|
209
|
+
@property
|
|
210
|
+
def is_setup(self) -> bool: ...
|
|
211
|
+
@property
|
|
212
|
+
def is_authenticated(self) -> bool:
|
|
213
|
+
"""
|
|
214
|
+
Indicates if the AMSDAL license authentication process has been passed.
|
|
215
|
+
|
|
216
|
+
This property returns a boolean value indicating whether the AMSDAL license
|
|
217
|
+
authentication process has been successfully completed.
|
|
218
|
+
|
|
219
|
+
Returns:
|
|
220
|
+
bool: True if authenticated, False otherwise.
|
|
221
|
+
"""
|
|
222
|
+
def pre_setup(self) -> None:
|
|
223
|
+
"""
|
|
224
|
+
Initiates models root path and adds it into sys.path.
|
|
225
|
+
|
|
226
|
+
This method initializes the class manager and sets up the models root path
|
|
227
|
+
as specified in the settings. It ensures that the models root path is added
|
|
228
|
+
to the system path for proper module resolution.
|
|
229
|
+
|
|
230
|
+
Returns:
|
|
231
|
+
None
|
|
232
|
+
"""
|
|
233
|
+
async def setup(self) -> None:
|
|
234
|
+
"""
|
|
235
|
+
Initiates models root path and the connections.
|
|
236
|
+
|
|
237
|
+
This method sets up the AMSDAL framework by initializing the models root path and
|
|
238
|
+
establishing connections. It ensures that the setup process is only performed once.
|
|
239
|
+
|
|
240
|
+
Raises:
|
|
241
|
+
AmsdalRuntimeError: If the AMSDAL manager is already set up.
|
|
242
|
+
|
|
243
|
+
Returns:
|
|
244
|
+
None
|
|
245
|
+
"""
|
|
246
|
+
async def post_setup(self) -> None:
|
|
247
|
+
"""
|
|
248
|
+
Registers internal classes and prepares connections (creates internal tables).
|
|
249
|
+
"""
|
|
250
|
+
def build(self, source_models_path: Path, source_transactions_path: Path, source_static_files_path: Path, source_fixtures_path: Path, source_migrations_path: Path) -> None:
|
|
251
|
+
"""
|
|
252
|
+
Builds the necessary components for the Amsdal framework.
|
|
253
|
+
|
|
254
|
+
This method is used to build the necessary components for the Amsdal framework.
|
|
255
|
+
It takes five parameters which are all of type `Path`.
|
|
256
|
+
These parameters represent the paths to the directories where the corresponding components are located.
|
|
257
|
+
|
|
258
|
+
Args:
|
|
259
|
+
source_models_path (Path): Path to the directory where the source models are located.
|
|
260
|
+
source_transactions_path (Path): Path to the directory where the source transactions are located.
|
|
261
|
+
source_static_files_path (Path): Path to the directory where the source static files are located.
|
|
262
|
+
source_fixtures_path (Path): Path to the directory where the source fixtures are located.
|
|
263
|
+
source_migrations_path (Path): Path to the directory where the source migrations are located.
|
|
264
|
+
|
|
265
|
+
Returns:
|
|
266
|
+
None
|
|
267
|
+
|
|
268
|
+
The method performs the following build steps in order:
|
|
269
|
+
- Builds the models from the `source_models_path` by calling the `build_models` method.
|
|
270
|
+
- Builds the transactions from the `source_transactions_path` by calling the `build_transactions` method.
|
|
271
|
+
- Builds the static files from the `source_static_files_path` by calling the `build_static_files` method.
|
|
272
|
+
- Builds the fixtures from the `source_fixtures_path` by calling the `build_fixtures` method.
|
|
273
|
+
|
|
274
|
+
Note:
|
|
275
|
+
This method is part of the `AmsdalManager` class which includes mixins for `BuildMixin`
|
|
276
|
+
and `ClassVersionsMixin`. It is intended to be used in the Amsdal framework for managing
|
|
277
|
+
and building components.
|
|
278
|
+
"""
|
|
279
|
+
def migrate(self) -> None:
|
|
280
|
+
"""
|
|
281
|
+
DEPRECATED: Check changes in the models and apply them to the database.
|
|
282
|
+
|
|
283
|
+
This method is deprecated and should not be used. It checks for changes in the models
|
|
284
|
+
and applies them to the database. Use `amsdal.migration.file_migration_generator.FileMigrationGenerator`
|
|
285
|
+
instead.
|
|
286
|
+
|
|
287
|
+
Raises:
|
|
288
|
+
DeprecationWarning: Always raised to indicate that this method is deprecated.
|
|
289
|
+
|
|
290
|
+
Returns:
|
|
291
|
+
None
|
|
292
|
+
"""
|
|
293
|
+
def _check_auth(self) -> None: ...
|
|
294
|
+
@property
|
|
295
|
+
def cloud_actions_manager(self) -> CloudActionsManager:
|
|
296
|
+
"""
|
|
297
|
+
Provides access to the CloudActionsManager.
|
|
298
|
+
|
|
299
|
+
This property checks if the AMSDAL manager is authenticated and then returns
|
|
300
|
+
an instance of the CloudActionsManager.
|
|
301
|
+
|
|
302
|
+
Returns:
|
|
303
|
+
CloudActionsManager: An instance of the CloudActionsManager.
|
|
304
|
+
|
|
305
|
+
Raises:
|
|
306
|
+
AmsdalAuthenticationError: If the AMSDAL manager is not authenticated.
|
|
307
|
+
"""
|
|
308
|
+
def authenticate(self) -> None:
|
|
309
|
+
"""
|
|
310
|
+
Run AMSDAL license authentication process.
|
|
311
|
+
|
|
312
|
+
This method runs the AMSDAL license authentication process and sets the
|
|
313
|
+
authentication status accordingly.
|
|
314
|
+
|
|
315
|
+
Returns:
|
|
316
|
+
None
|
|
317
|
+
"""
|
|
318
|
+
async def apply_fixtures(self) -> None:
|
|
319
|
+
"""
|
|
320
|
+
Loads and applies fixtures defined in your application.
|
|
321
|
+
|
|
322
|
+
This method loads the fixtures from the specified path and applies them to the
|
|
323
|
+
AMSDAL framework. It uses the `FixturesManager` to manage the loading and application
|
|
324
|
+
of the fixtures.
|
|
325
|
+
|
|
326
|
+
Returns:
|
|
327
|
+
None
|
|
328
|
+
"""
|
|
329
|
+
def init_classes(self) -> None:
|
|
330
|
+
"""
|
|
331
|
+
Initializes and imports classes based on the schema manager's class schemas.
|
|
332
|
+
|
|
333
|
+
This method iterates over the class schemas provided by the schema manager and imports
|
|
334
|
+
the classes into the class manager, excluding those of type `SchemaTypes.TYPE`.
|
|
335
|
+
|
|
336
|
+
Returns:
|
|
337
|
+
None
|
|
338
|
+
"""
|
|
339
|
+
async def teardown(self) -> None:
|
|
340
|
+
"""
|
|
341
|
+
Clean up everything on the application exit.
|
|
342
|
+
|
|
343
|
+
This method performs a cleanup of all components managed by the AMSDAL framework
|
|
344
|
+
when the application exits. It disconnects and invalidates connections, clears caches,
|
|
345
|
+
and resets the setup status.
|
|
346
|
+
|
|
347
|
+
Raises:
|
|
348
|
+
AmsdalRuntimeError: If the AMSDAL manager is not set up.
|
|
349
|
+
|
|
350
|
+
Returns:
|
|
351
|
+
None
|
|
352
|
+
"""
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -104,3 +104,15 @@ class BaseMigrationExecutor(ABC, metaclass=abc.ABCMeta):
|
|
|
104
104
|
Returns:
|
|
105
105
|
None
|
|
106
106
|
"""
|
|
107
|
+
|
|
108
|
+
class AsyncBaseMigrationExecutor(BaseMigrationExecutor, metaclass=abc.ABCMeta):
|
|
109
|
+
async def flush_buffer(self) -> None:
|
|
110
|
+
"""
|
|
111
|
+
Flushes the migration buffer.
|
|
112
|
+
|
|
113
|
+
This method clears all entries from the main migration buffer, effectively
|
|
114
|
+
resetting it for future migration operations.
|
|
115
|
+
|
|
116
|
+
Returns:
|
|
117
|
+
None
|
|
118
|
+
"""
|
|
Binary file
|
|
@@ -3,7 +3,7 @@ from _typeshed import Incomplete
|
|
|
3
3
|
from amsdal.errors import MigrationsError as MigrationsError
|
|
4
4
|
from amsdal.migration.base_migration_schemas import BaseMigrationSchemas as BaseMigrationSchemas
|
|
5
5
|
from amsdal.migration.data_classes import Action as Action
|
|
6
|
-
from amsdal.migration.executors.base import BaseMigrationExecutor as BaseMigrationExecutor
|
|
6
|
+
from amsdal.migration.executors.base import AsyncBaseMigrationExecutor as AsyncBaseMigrationExecutor, BaseMigrationExecutor as BaseMigrationExecutor
|
|
7
7
|
from amsdal_models.classes.model import Model
|
|
8
8
|
from amsdal_utils.models.data_models.schema import ObjectSchema
|
|
9
9
|
from amsdal_utils.models.enums import SchemaTypes, Versions
|
|
@@ -95,3 +95,90 @@ class DefaultMigrationExecutor(BaseMigrationExecutor):
|
|
|
95
95
|
Returns:
|
|
96
96
|
None
|
|
97
97
|
"""
|
|
98
|
+
|
|
99
|
+
class DefaultAsyncMigrationExecutor(AsyncBaseMigrationExecutor):
|
|
100
|
+
"""
|
|
101
|
+
Default implementation of the BaseMigrationExecutor for handling database schema migrations.
|
|
102
|
+
|
|
103
|
+
This class provides concrete implementations for creating, updating, and deleting classes
|
|
104
|
+
in the database schema. It also manages schema migration buffers and processes object schemas.
|
|
105
|
+
"""
|
|
106
|
+
schemas: Incomplete
|
|
107
|
+
_table_schemas_manager: Incomplete
|
|
108
|
+
def __init__(self, schemas: BaseMigrationSchemas) -> None: ...
|
|
109
|
+
def create_class(self, schemas: BaseMigrationSchemas, class_name: str, object_schema: ObjectSchema, schema_type: SchemaTypes) -> None:
|
|
110
|
+
"""
|
|
111
|
+
Creates a class in the database schema.
|
|
112
|
+
|
|
113
|
+
This method registers a new class version if the schema type is `TYPE` and the class name
|
|
114
|
+
is not `BaseClasses.OBJECT`.
|
|
115
|
+
Otherwise, it buffers the class migration operation for further processing.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
schemas (BaseMigrationSchemas): The migration schemas used for the operations.
|
|
119
|
+
class_name (str): The name of the class to be created.
|
|
120
|
+
object_schema (ObjectSchema): The schema of the object to be created.
|
|
121
|
+
schema_type (SchemaTypes): The type of the schema.
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
None
|
|
125
|
+
"""
|
|
126
|
+
def update_class(self, schemas: BaseMigrationSchemas, class_name: str, object_schema: ObjectSchema, schema_type: SchemaTypes) -> None:
|
|
127
|
+
"""
|
|
128
|
+
Buffers the class update operation.
|
|
129
|
+
|
|
130
|
+
This method appends the given class name, object schema, and schema type to both
|
|
131
|
+
the non-flushable buffer and the main buffer for further processing.
|
|
132
|
+
|
|
133
|
+
Args:
|
|
134
|
+
schemas (BaseMigrationSchemas): The migration schemas used for the operations.
|
|
135
|
+
class_name (str): The name of the class to be updated.
|
|
136
|
+
object_schema (ObjectSchema): The current object schema.
|
|
137
|
+
schema_type (SchemaTypes): The type of the schema.
|
|
138
|
+
|
|
139
|
+
Returns:
|
|
140
|
+
None
|
|
141
|
+
"""
|
|
142
|
+
async def delete_class(self, schemas: BaseMigrationSchemas, class_name: str, schema_type: SchemaTypes) -> None:
|
|
143
|
+
"""
|
|
144
|
+
Deletes a class from the database schema.
|
|
145
|
+
|
|
146
|
+
This method removes the specified class from the database schema and unregisters it from the migration schemas.
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
schemas (BaseMigrationSchemas): The migration schemas used for the operations.
|
|
150
|
+
class_name (str): The name of the class to be deleted.
|
|
151
|
+
schema_type (SchemaTypes): The type of the schema.
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
None
|
|
155
|
+
"""
|
|
156
|
+
async def flush_buffer(self) -> None:
|
|
157
|
+
"""
|
|
158
|
+
Flushes the migration buffer and processes the buffered classes.
|
|
159
|
+
|
|
160
|
+
This method registers the buffered classes in the migration schemas, compiles the buffered classes,
|
|
161
|
+
and processes each class in the buffer to create tables, save class objects, and migrate historical data.
|
|
162
|
+
Finally, it clears the main migration buffer.
|
|
163
|
+
|
|
164
|
+
Returns:
|
|
165
|
+
None
|
|
166
|
+
"""
|
|
167
|
+
async def _check_class(self, schema_reference: glue.SchemaReference, object_schema: ObjectSchema, base_class: type[Model]) -> Action: ...
|
|
168
|
+
async def _save_class(self, schema_reference: glue.SchemaReference, base_class: type[Model], object_schema: ObjectSchema, action: Action) -> dict[str, Any]: ...
|
|
169
|
+
async def _save_object_class_meta(self, base_class: type[Model], object_schema: ObjectSchema, schema_type: SchemaTypes) -> None: ...
|
|
170
|
+
async def _create_table(self, object_schema: ObjectSchema, class_version: str | Versions, using: str | None = None) -> None: ...
|
|
171
|
+
async def _migrate_historical_data(self, schemas: BaseMigrationSchemas, class_name: str, prior_version: str, new_version: str) -> None: ...
|
|
172
|
+
def _clean_data(self, model_class: type[Model], data: dict[str, Any]) -> dict[str, Any]: ...
|
|
173
|
+
def _process_object_schema(self, object_schema: ObjectSchema, class_name: str, buffer: list[tuple[str, ObjectSchema, SchemaTypes]]) -> ObjectSchema: ...
|
|
174
|
+
async def register_schemas(self) -> None:
|
|
175
|
+
"""
|
|
176
|
+
Registers the schemas in the table schemas manager.
|
|
177
|
+
|
|
178
|
+
This method retrieves the object schemas from the database, processes them, and registers
|
|
179
|
+
them in the table schemas manager. It handles both `ClassObject` and `ClassObjectMeta` schemas,
|
|
180
|
+
and ensures that all necessary references are loaded and processed.
|
|
181
|
+
|
|
182
|
+
Returns:
|
|
183
|
+
None
|
|
184
|
+
"""
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,6 +1,12 @@
|
|
|
1
|
+
from amsdal_data.connections.historical.schema_version_manager import AsyncHistoricalSchemaVersionManager, HistoricalSchemaVersionManager
|
|
2
|
+
|
|
1
3
|
class ClassVersionsMixin:
|
|
2
4
|
"""
|
|
3
5
|
Mixin class to manage class versions and related table schemas.
|
|
4
6
|
"""
|
|
5
7
|
@staticmethod
|
|
6
|
-
def
|
|
8
|
+
def _register_internal_classes(schema_version_manager: HistoricalSchemaVersionManager | AsyncHistoricalSchemaVersionManager) -> None: ...
|
|
9
|
+
@classmethod
|
|
10
|
+
def register_internal_classes(cls) -> None: ...
|
|
11
|
+
@classmethod
|
|
12
|
+
def aregister_internal_classes(cls) -> None: ...
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import amsdal_glue as glue
|
|
2
|
+
from amsdal_data.application import AsyncDataApplication
|
|
2
3
|
from amsdal_data.application import DataApplication
|
|
4
|
+
from amsdal_data.transactions.decorators import async_transaction
|
|
3
5
|
from amsdal_data.transactions.decorators import transaction
|
|
4
6
|
from amsdal_data.transactions.errors import AmsdalTransactionError
|
|
5
7
|
from amsdal_models.classes.manager import ClassManager
|
|
@@ -198,3 +200,196 @@ def rollback_transaction(transaction_id: str) -> None:
|
|
|
198
200
|
|
|
199
201
|
updated_at = metadatas_to_revert[0].data['updated_at']
|
|
200
202
|
rollback_to_timestamp(updated_at)
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
@async_transaction
|
|
206
|
+
async def async_rollback_to_timestamp(timestamp: float) -> None:
|
|
207
|
+
"""
|
|
208
|
+
Rollback the data to the given timestamp
|
|
209
|
+
Args:
|
|
210
|
+
timestamp (float): The timestamp to rollback the data to.
|
|
211
|
+
Returns:
|
|
212
|
+
None
|
|
213
|
+
"""
|
|
214
|
+
class_manager = ClassManager()
|
|
215
|
+
|
|
216
|
+
lakehouse_connection = await (
|
|
217
|
+
AsyncDataApplication()._application.lakehouse_connection_manager.get_connection_pool('Company').get_connection()
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
metadatas_to_delete = await lakehouse_connection.query(
|
|
221
|
+
query=glue.QueryStatement(
|
|
222
|
+
table=glue.SchemaReference(name='Metadata', version=glue.Version.LATEST),
|
|
223
|
+
where=glue.Conditions(
|
|
224
|
+
glue.Condition(
|
|
225
|
+
field=glue.FieldReference(field=glue.Field(name='updated_at'), table_name='Metadata'),
|
|
226
|
+
lookup=glue.FieldLookup.GT,
|
|
227
|
+
value=glue.Value(timestamp),
|
|
228
|
+
),
|
|
229
|
+
glue.Condition(
|
|
230
|
+
field=glue.FieldReference(field=glue.Field(name='prior_version'), table_name='Metadata'),
|
|
231
|
+
lookup=glue.FieldLookup.ISNULL,
|
|
232
|
+
value=glue.Value(True),
|
|
233
|
+
),
|
|
234
|
+
),
|
|
235
|
+
)
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
ids_to_ignore = [m.data['object_id'] for m in metadatas_to_delete]
|
|
239
|
+
|
|
240
|
+
metadatas_to_revert = await lakehouse_connection.query(
|
|
241
|
+
query=glue.QueryStatement(
|
|
242
|
+
table=glue.SchemaReference(name='Metadata', version=glue.Version.LATEST),
|
|
243
|
+
where=glue.Conditions(
|
|
244
|
+
glue.Condition(
|
|
245
|
+
field=glue.FieldReference(field=glue.Field(name='updated_at'), table_name='Metadata'),
|
|
246
|
+
lookup=glue.FieldLookup.GT,
|
|
247
|
+
value=glue.Value(timestamp),
|
|
248
|
+
),
|
|
249
|
+
glue.Condition(
|
|
250
|
+
field=glue.FieldReference(field=glue.Field(name='prior_version'), table_name='Metadata'),
|
|
251
|
+
lookup=glue.FieldLookup.ISNULL,
|
|
252
|
+
value=glue.Value(False),
|
|
253
|
+
),
|
|
254
|
+
),
|
|
255
|
+
)
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
transaction_ids = {m.data['transaction']['ref']['object_id'] for m in metadatas_to_revert}
|
|
259
|
+
transaction_ids.update({m.data['transaction']['ref']['object_id'] for m in metadatas_to_delete})
|
|
260
|
+
ids_to_revert = [
|
|
261
|
+
(m.data['object_id'], m.data['class_schema_reference']['ref']['object_id'])
|
|
262
|
+
for m in metadatas_to_revert
|
|
263
|
+
if m.data['object_id'] not in ids_to_ignore
|
|
264
|
+
]
|
|
265
|
+
|
|
266
|
+
if transaction_ids:
|
|
267
|
+
_conditions = []
|
|
268
|
+
for transaction_id in transaction_ids:
|
|
269
|
+
_parent_field = glue.Field(
|
|
270
|
+
name='transaction',
|
|
271
|
+
child=glue.Field(
|
|
272
|
+
name='ref',
|
|
273
|
+
child=glue.Field(name='object_id'),
|
|
274
|
+
),
|
|
275
|
+
)
|
|
276
|
+
_parent_field.child.parent = _parent_field # type: ignore[union-attr]
|
|
277
|
+
_parent_field.child.child.parent = _parent_field.child # type: ignore[union-attr]
|
|
278
|
+
_conditions.append(
|
|
279
|
+
glue.Condition(
|
|
280
|
+
field=glue.FieldReference(field=_parent_field, table_name='Metadata'),
|
|
281
|
+
lookup=glue.FieldLookup.EQ,
|
|
282
|
+
value=glue.Value(transaction_id),
|
|
283
|
+
)
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
conflict_metadata = await lakehouse_connection.query(
|
|
287
|
+
query=glue.QueryStatement(
|
|
288
|
+
table=glue.SchemaReference(name='Metadata', version=glue.Version.LATEST),
|
|
289
|
+
where=glue.Conditions(
|
|
290
|
+
glue.Condition(
|
|
291
|
+
field=glue.FieldReference(field=glue.Field(name='updated_at'), table_name='Metadata'),
|
|
292
|
+
lookup=glue.FieldLookup.LTE,
|
|
293
|
+
value=glue.Value(timestamp),
|
|
294
|
+
),
|
|
295
|
+
glue.Conditions(*_conditions, connector=glue.FilterConnector.OR),
|
|
296
|
+
),
|
|
297
|
+
)
|
|
298
|
+
)
|
|
299
|
+
if conflict_metadata:
|
|
300
|
+
msg = 'Cannot rollback to this timestamp because it will conflict with other transactions'
|
|
301
|
+
raise AmsdalTransactionError(msg)
|
|
302
|
+
|
|
303
|
+
for m in metadatas_to_delete:
|
|
304
|
+
class_name = m.data['class_schema_reference']['ref']['object_id']
|
|
305
|
+
schema_type = class_manager.resolve_schema_type(class_name)
|
|
306
|
+
|
|
307
|
+
model_class = class_manager.import_model_class(class_name, schema_type)
|
|
308
|
+
obj = await (
|
|
309
|
+
model_class.objects.filter(_address__object_id=m.data['object_id'])
|
|
310
|
+
.using(LAKEHOUSE_DB_ALIAS)
|
|
311
|
+
.latest()
|
|
312
|
+
.first()
|
|
313
|
+
.aexecute()
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
if obj and not (await obj.aget_metadata()).is_deleted:
|
|
317
|
+
await obj.adelete()
|
|
318
|
+
|
|
319
|
+
for object_id, class_name in ids_to_revert:
|
|
320
|
+
schema_type = class_manager.resolve_schema_type(class_name)
|
|
321
|
+
model_class = class_manager.import_model_class(class_name, schema_type)
|
|
322
|
+
|
|
323
|
+
obj = await (
|
|
324
|
+
model_class.objects.filter(_address__object_id=object_id)
|
|
325
|
+
.using(LAKEHOUSE_DB_ALIAS)
|
|
326
|
+
.latest()
|
|
327
|
+
.first()
|
|
328
|
+
.aexecute()
|
|
329
|
+
)
|
|
330
|
+
old_obj = await (
|
|
331
|
+
model_class.objects.filter(_address__object_id=object_id, _metadata__updated_at__lte=timestamp)
|
|
332
|
+
.using(LAKEHOUSE_DB_ALIAS)
|
|
333
|
+
.order_by('-_metadata__updated_at')
|
|
334
|
+
.first()
|
|
335
|
+
.aexecute()
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
if obj and old_obj:
|
|
339
|
+
for field, value in old_obj.model_dump().items():
|
|
340
|
+
setattr(obj, field, value)
|
|
341
|
+
|
|
342
|
+
await obj.asave()
|
|
343
|
+
|
|
344
|
+
if (await old_obj.aget_metadata()).is_deleted:
|
|
345
|
+
await obj.adelete()
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
@async_transaction
|
|
349
|
+
async def async_rollback_transaction(transaction_id: str) -> None:
|
|
350
|
+
"""
|
|
351
|
+
Rollback the data to the point in time before the given transaction
|
|
352
|
+
Args:
|
|
353
|
+
transaction_id (str): The transaction ID to rollback the data to.
|
|
354
|
+
Returns:
|
|
355
|
+
None
|
|
356
|
+
"""
|
|
357
|
+
lakehouse_connection = await (
|
|
358
|
+
AsyncDataApplication()._application.lakehouse_connection_manager.get_connection_pool('Company').get_connection()
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
_parent_field = glue.Field(
|
|
362
|
+
name='transaction',
|
|
363
|
+
child=glue.Field(
|
|
364
|
+
name='ref',
|
|
365
|
+
child=glue.Field(name='object_id'),
|
|
366
|
+
),
|
|
367
|
+
)
|
|
368
|
+
_parent_field.child.parent = _parent_field # type: ignore[union-attr]
|
|
369
|
+
_parent_field.child.child.parent = _parent_field.child # type: ignore[union-attr]
|
|
370
|
+
|
|
371
|
+
metadatas_to_revert = await lakehouse_connection.query(
|
|
372
|
+
query=glue.QueryStatement(
|
|
373
|
+
table=glue.SchemaReference(name='Metadata', version=glue.Version.LATEST),
|
|
374
|
+
where=glue.Conditions(
|
|
375
|
+
glue.Condition(
|
|
376
|
+
field=glue.FieldReference(field=_parent_field, table_name='Metadata'),
|
|
377
|
+
lookup=glue.FieldLookup.EQ,
|
|
378
|
+
value=glue.Value(transaction_id),
|
|
379
|
+
)
|
|
380
|
+
),
|
|
381
|
+
order_by=[
|
|
382
|
+
glue.OrderByQuery(
|
|
383
|
+
field=glue.FieldReference(field=glue.Field(name='updated_at'), table_name='Metadata'),
|
|
384
|
+
direction=glue.OrderDirection.DESC,
|
|
385
|
+
)
|
|
386
|
+
],
|
|
387
|
+
)
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
if not metadatas_to_revert:
|
|
391
|
+
msg = 'Transaction not found'
|
|
392
|
+
raise AmsdalTransactionError(msg)
|
|
393
|
+
|
|
394
|
+
updated_at = metadatas_to_revert[0].data['updated_at']
|
|
395
|
+
await async_rollback_to_timestamp(updated_at) # type: ignore[misc]
|
|
@@ -14,3 +14,19 @@ def rollback_transaction(transaction_id: str) -> None:
|
|
|
14
14
|
Returns:
|
|
15
15
|
None
|
|
16
16
|
"""
|
|
17
|
+
async def async_rollback_to_timestamp(timestamp: float) -> None:
|
|
18
|
+
"""
|
|
19
|
+
Rollback the data to the given timestamp
|
|
20
|
+
Args:
|
|
21
|
+
timestamp (float): The timestamp to rollback the data to.
|
|
22
|
+
Returns:
|
|
23
|
+
None
|
|
24
|
+
"""
|
|
25
|
+
async def async_rollback_transaction(transaction_id: str) -> None:
|
|
26
|
+
"""
|
|
27
|
+
Rollback the data to the point in time before the given transaction
|
|
28
|
+
Args:
|
|
29
|
+
transaction_id (str): The transaction ID to rollback the data to.
|
|
30
|
+
Returns:
|
|
31
|
+
None
|
|
32
|
+
"""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: amsdal
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: AMSDAL
|
|
5
5
|
License: AMSDAL End User License Agreement
|
|
6
6
|
|
|
@@ -133,13 +133,15 @@ Requires-Dist: amsdal_utils==0.3.*
|
|
|
133
133
|
Requires-Dist: amsdal_data[postgres-binary]==0.3.*
|
|
134
134
|
Requires-Dist: amsdal_models==0.3.*
|
|
135
135
|
Provides-Extra: cli
|
|
136
|
-
Requires-Dist: amsdal-cli==0.
|
|
136
|
+
Requires-Dist: amsdal-cli==0.3.*; extra == "cli"
|
|
137
137
|
Provides-Extra: server
|
|
138
|
-
Requires-Dist: amsdal-server==0.
|
|
138
|
+
Requires-Dist: amsdal-server==0.3.*; extra == "server"
|
|
139
139
|
Provides-Extra: factory
|
|
140
140
|
Requires-Dist: polyfactory==2.*; extra == "factory"
|
|
141
141
|
Provides-Extra: celery
|
|
142
142
|
Requires-Dist: celery==5.4.0; extra == "celery"
|
|
143
|
+
Provides-Extra: aiosqlite
|
|
144
|
+
Requires-Dist: aiosqlite>=0.20.0; extra == "aiosqlite"
|
|
143
145
|
|
|
144
146
|
# AMSDAL
|
|
145
147
|
|