wiederverwendbar 0.8.3__tar.gz → 0.8.5__tar.gz
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.
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/PKG-INFO +14 -14
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/pyproject.toml +14 -14
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/__init__.py +1 -1
- wiederverwendbar-0.8.5/src/wiederverwendbar/examples/sqlalchemy/db.py +89 -0
- wiederverwendbar-0.8.5/src/wiederverwendbar/functions/get_pretty_str.py +9 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/sqlalchemy/base.py +31 -2
- wiederverwendbar-0.8.5/src/wiederverwendbar/sqlalchemy/db.py +278 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/sqlalchemy/settings.py +9 -0
- wiederverwendbar-0.8.3/src/wiederverwendbar/examples/sqlalchemy/db.py +0 -31
- wiederverwendbar-0.8.3/src/wiederverwendbar/sqlalchemy/db.py +0 -152
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/README.md +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/before_after_wrap.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/default.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/before_after_wrap.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/colors.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/extended_thread.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/file_config.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/indexable_model.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/logger.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/logger_context/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/logger_context/example.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/logger_context/example_module.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/mongoengine/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/mongoengine/automatic_reference.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/mongoengine/db.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/mongoengine/log_streamer.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/mongoengine/logger.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/post_init.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/route.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/singletons.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/sqlalchemy/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/starlette_admin/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/starlette_admin/action_log.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/starlette_admin/action_log_file_download.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/starlette_admin/action_log_form.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/starlette_admin/action_log_thread.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/starlette_admin/automatic_reference_admin.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/starlette_admin/generic_embedded_document_field.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/starlette_admin/multi_path_admin.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/task_manager.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/test_file.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/typer_resolve_defaults.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/examples/uvicorn_server.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/admin.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/animal_name_generator.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/case_converter.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/check_hash_file.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/colors.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/datetime.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/download_file.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/eval.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/find_class_method.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/run_command.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/security/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/security/hashed_password.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/test_file.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/functions/wait_ping.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/logger/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/logger/context.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/logger/file_modes.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/logger/handlers/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/logger/handlers/rich_console_handler.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/logger/handlers/stream_console_handler.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/logger/handlers/tar_rotating_file_handler.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/logger/helper.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/logger/log_levels.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/logger/logger.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/logger/settings.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/logger/singleton.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/logger/terminal_out_files.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/automatic_reference.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/backup.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/db.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/fields/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/fields/boolean_also_field.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/fields/domain_field.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/fields/ipv4_address_field.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/fields/ipv4_network_field.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/fields/port_field.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/fields/with_instance_field.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/logger/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/logger/documets.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/logger/formatters.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/logger/handlers.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/logger/streamer.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/property_document.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/security/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/security/hashed_password.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/settings.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/mongoengine/singleton.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/post_init.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/pydantic/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/pydantic/file_config.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/pydantic/indexable_model.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/pydantic/printable_settings.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/pydantic/security/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/pydantic/security/hashed_password.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/pydantic/singleton.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/route.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/singleton.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/sqlalchemy/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/sqlalchemy/raise_has_not_attr.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/sqlalchemy/singleton.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/sqlalchemy/types.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/action_log/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/action_log/admin.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/action_log/logger.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/action_log/settings.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/action_log/statics/js/actions.js +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/action_log/templates/modals/loading.html +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/action_log/thread.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/admin.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/drop_down_icon_view/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/drop_down_icon_view/admin.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/drop_down_icon_view/templates/macros/views.html +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/drop_down_icon_view/views.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/form_max_fields/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/form_max_fields/admin.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/form_max_fields/settings.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/auth/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/auth/admin.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/auth/documents/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/auth/documents/session.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/auth/documents/user.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/auth/provider.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/auth/settings.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/auth/views/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/auth/views/auth.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/auth/views/session.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/auth/views/user.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/boolean_also_field/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/boolean_also_field/admin.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/boolean_also_field/converter.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/boolean_also_field/field.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/boolean_also_field/statics/js/boolean_also_field.js +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/boolean_also_field/templates/forms/boolean.html +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/converter.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/generic_embedded_document_field/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/generic_embedded_document_field/admin.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/generic_embedded_document_field/converter.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/generic_embedded_document_field/field.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/generic_embedded_document_field/statics/js/form.js +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/generic_embedded_document_field/statics/js/generic_embedded.js +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/generic_embedded_document_field/templates/displays/generic_embedded.html +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/generic_embedded_document_field/templates/forms/generic_embedded.html +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/generic_embedded_document_field/view.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/helper.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/ipv4_field/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/ipv4_field/converter.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/mongoengine/view.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/multi_path/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/multi_path/admin.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/settings/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/settings/admin.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/starlette_admin/settings/settings.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/task_manger/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/task_manger/singleton.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/task_manger/task.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/task_manger/task_manager.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/task_manger/trigger.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/threading/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/threading/extended_thread.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/typer/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/typer/typer_resolve_defaults.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/uvicorn/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/uvicorn/server.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/uvicorn/settings.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/tests/__init__.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/tests/frontend.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/tests/meta.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/tests/shared.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/tests/task_manager.py +0 -0
- {wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/tests/worker.py +0 -0
@@ -1,49 +1,49 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: wiederverwendbar
|
3
|
-
Version: 0.8.
|
3
|
+
Version: 0.8.5
|
4
4
|
Summary: A collection of scripts, classes and tools they are \"wiederverwendbar\".
|
5
5
|
Author-Email: Julius Koenig <info@bastelquartier.de>
|
6
6
|
License: GPL-3.0
|
7
7
|
Requires-Python: >=3.9
|
8
|
-
Requires-Dist: pydantic>=2.11.
|
8
|
+
Requires-Dist: pydantic>=2.11.5
|
9
9
|
Requires-Dist: pydantic-settings>=2.9.1
|
10
10
|
Requires-Dist: devtools>=0.12.2
|
11
11
|
Provides-Extra: full
|
12
12
|
Requires-Dist: rich>=14.0.0; extra == "full"
|
13
|
-
Requires-Dist: typer>=0.
|
13
|
+
Requires-Dist: typer>=0.16.0; extra == "full"
|
14
14
|
Requires-Dist: pythonping>=1.1.4; extra == "full"
|
15
15
|
Requires-Dist: mongoengine>=0.29.1; extra == "full"
|
16
|
-
Requires-Dist: nicegui>=2.
|
17
|
-
Requires-Dist: uvicorn>=0.34.
|
16
|
+
Requires-Dist: nicegui>=2.19.0; extra == "full"
|
17
|
+
Requires-Dist: uvicorn>=0.34.3; extra == "full"
|
18
18
|
Requires-Dist: fastapi>=0.115.12; extra == "full"
|
19
|
-
Requires-Dist: starlette-admin[i18n]>=0.
|
19
|
+
Requires-Dist: starlette-admin[i18n]>=0.15.1; extra == "full"
|
20
20
|
Requires-Dist: pillow>=11.2.1; extra == "full"
|
21
21
|
Requires-Dist: blinker>=1.9.0; extra == "full"
|
22
|
-
Requires-Dist: kombu>=5.5.
|
22
|
+
Requires-Dist: kombu>=5.5.4; extra == "full"
|
23
23
|
Requires-Dist: nest-asyncio>=1.6.0; extra == "full"
|
24
|
-
Requires-Dist: sqlalchemy>=2.0.
|
24
|
+
Requires-Dist: sqlalchemy>=2.0.41; extra == "full"
|
25
25
|
Provides-Extra: rich
|
26
26
|
Requires-Dist: rich>=14.0.0; extra == "rich"
|
27
27
|
Provides-Extra: typer
|
28
|
-
Requires-Dist: typer>=0.
|
28
|
+
Requires-Dist: typer>=0.16.0; extra == "typer"
|
29
29
|
Provides-Extra: mongoengine
|
30
30
|
Requires-Dist: mongoengine>=0.29.1; extra == "mongoengine"
|
31
31
|
Requires-Dist: blinker>=1.9.0; extra == "mongoengine"
|
32
32
|
Provides-Extra: uvicorn
|
33
|
-
Requires-Dist: uvicorn>=0.34.
|
33
|
+
Requires-Dist: uvicorn>=0.34.3; extra == "uvicorn"
|
34
34
|
Provides-Extra: fastapi
|
35
35
|
Requires-Dist: fastapi>=0.115.12; extra == "fastapi"
|
36
36
|
Provides-Extra: nicegui
|
37
|
-
Requires-Dist: nicegui>=2.
|
37
|
+
Requires-Dist: nicegui>=2.19.0; extra == "nicegui"
|
38
38
|
Provides-Extra: starlette-admin
|
39
|
-
Requires-Dist: starlette-admin[i18n]>=0.
|
39
|
+
Requires-Dist: starlette-admin[i18n]>=0.15.1; extra == "starlette-admin"
|
40
40
|
Requires-Dist: pillow>=11.2.1; extra == "starlette-admin"
|
41
|
-
Requires-Dist: kombu>=5.5.
|
41
|
+
Requires-Dist: kombu>=5.5.4; extra == "starlette-admin"
|
42
42
|
Requires-Dist: nest-asyncio>=1.6.0; extra == "starlette-admin"
|
43
43
|
Provides-Extra: fuctions
|
44
44
|
Requires-Dist: pythonping>=1.1.4; extra == "fuctions"
|
45
45
|
Provides-Extra: sqlalchemy
|
46
|
-
Requires-Dist: sqlalchemy>=2.0.
|
46
|
+
Requires-Dist: sqlalchemy>=2.0.41; extra == "sqlalchemy"
|
47
47
|
Description-Content-Type: text/markdown
|
48
48
|
|
49
49
|
# wiederverwendbar
|
@@ -6,13 +6,13 @@ authors = [
|
|
6
6
|
{ name = "Julius Koenig", email = "info@bastelquartier.de" },
|
7
7
|
]
|
8
8
|
dependencies = [
|
9
|
-
"pydantic>=2.11.
|
9
|
+
"pydantic>=2.11.5",
|
10
10
|
"pydantic-settings>=2.9.1",
|
11
11
|
"devtools>=0.12.2",
|
12
12
|
]
|
13
13
|
requires-python = ">=3.9"
|
14
14
|
readme = "README.md"
|
15
|
-
version = "0.8.
|
15
|
+
version = "0.8.5"
|
16
16
|
|
17
17
|
[project.license]
|
18
18
|
text = "GPL-3.0"
|
@@ -20,49 +20,49 @@ text = "GPL-3.0"
|
|
20
20
|
[project.optional-dependencies]
|
21
21
|
full = [
|
22
22
|
"rich>=14.0.0",
|
23
|
-
"typer>=0.
|
23
|
+
"typer>=0.16.0",
|
24
24
|
"pythonping>=1.1.4",
|
25
25
|
"mongoengine>=0.29.1",
|
26
|
-
"nicegui>=2.
|
27
|
-
"uvicorn>=0.34.
|
26
|
+
"nicegui>=2.19.0",
|
27
|
+
"uvicorn>=0.34.3",
|
28
28
|
"fastapi>=0.115.12",
|
29
|
-
"starlette-admin[i18n]>=0.
|
29
|
+
"starlette-admin[i18n]>=0.15.1",
|
30
30
|
"pillow>=11.2.1",
|
31
31
|
"blinker>=1.9.0",
|
32
|
-
"kombu>=5.5.
|
32
|
+
"kombu>=5.5.4",
|
33
33
|
"nest-asyncio>=1.6.0",
|
34
|
-
"sqlalchemy>=2.0.
|
34
|
+
"sqlalchemy>=2.0.41",
|
35
35
|
]
|
36
36
|
rich = [
|
37
37
|
"rich>=14.0.0",
|
38
38
|
]
|
39
39
|
typer = [
|
40
|
-
"typer>=0.
|
40
|
+
"typer>=0.16.0",
|
41
41
|
]
|
42
42
|
mongoengine = [
|
43
43
|
"mongoengine>=0.29.1",
|
44
44
|
"blinker>=1.9.0",
|
45
45
|
]
|
46
46
|
uvicorn = [
|
47
|
-
"uvicorn>=0.34.
|
47
|
+
"uvicorn>=0.34.3",
|
48
48
|
]
|
49
49
|
fastapi = [
|
50
50
|
"fastapi>=0.115.12",
|
51
51
|
]
|
52
52
|
nicegui = [
|
53
|
-
"nicegui>=2.
|
53
|
+
"nicegui>=2.19.0",
|
54
54
|
]
|
55
55
|
starlette-admin = [
|
56
|
-
"starlette-admin[i18n]>=0.
|
56
|
+
"starlette-admin[i18n]>=0.15.1",
|
57
57
|
"pillow>=11.2.1",
|
58
|
-
"kombu>=5.5.
|
58
|
+
"kombu>=5.5.4",
|
59
59
|
"nest-asyncio>=1.6.0",
|
60
60
|
]
|
61
61
|
fuctions = [
|
62
62
|
"pythonping>=1.1.4",
|
63
63
|
]
|
64
64
|
sqlalchemy = [
|
65
|
-
"sqlalchemy>=2.0.
|
65
|
+
"sqlalchemy>=2.0.41",
|
66
66
|
]
|
67
67
|
|
68
68
|
[build-system]
|
@@ -0,0 +1,89 @@
|
|
1
|
+
from pathlib import Path
|
2
|
+
from typing import Optional
|
3
|
+
|
4
|
+
from sqlalchemy import Column, ForeignKey, Integer, Text
|
5
|
+
|
6
|
+
from sqlalchemy.orm import relationship
|
7
|
+
|
8
|
+
from wiederverwendbar.logger import LoggerSingleton, LoggerSettings, LogLevels
|
9
|
+
from wiederverwendbar.sqlalchemy import Base, SqlalchemySettings, SqlalchemyDbSingleton
|
10
|
+
|
11
|
+
LoggerSingleton(name="test", settings=LoggerSettings(log_level=LogLevels.DEBUG), init=True)
|
12
|
+
SqlalchemyDbSingleton(settings=SqlalchemySettings(db_file=Path("test.db")), init=True)
|
13
|
+
|
14
|
+
|
15
|
+
class MyBase(Base, SqlalchemyDbSingleton().Base):
|
16
|
+
__abstract__ = True
|
17
|
+
|
18
|
+
|
19
|
+
class Parent(MyBase):
|
20
|
+
__tablename__ = "parent"
|
21
|
+
__str_columns__: list[str] = ["id", "name"]
|
22
|
+
|
23
|
+
id: int = Column(Integer(), primary_key=True, autoincrement=True, name="parent_id")
|
24
|
+
name: str = Column(Text(50), nullable=False, unique=True)
|
25
|
+
children: list["Child"] = relationship("Child",
|
26
|
+
foreign_keys="Child.parent_id",
|
27
|
+
primaryjoin="Parent.id == Child.parent_id",
|
28
|
+
viewonly=True)
|
29
|
+
|
30
|
+
|
31
|
+
class Child(MyBase):
|
32
|
+
__tablename__ = "child"
|
33
|
+
__str_columns__: list[str] = ["id", "name"]
|
34
|
+
|
35
|
+
id: int = Column(Integer(), primary_key=True, autoincrement=True, name="parent_id")
|
36
|
+
name: str = Column(Text(50), nullable=False, unique=True)
|
37
|
+
parent_id: int = Column(Integer(), ForeignKey("parent.parent_id"), nullable=False, name="child_parent_id")
|
38
|
+
parent: Optional[Parent] = relationship("Parent",
|
39
|
+
foreign_keys="Parent.id",
|
40
|
+
primaryjoin="Child.parent_id == Parent.id")
|
41
|
+
|
42
|
+
|
43
|
+
if __name__ == '__main__':
|
44
|
+
SqlalchemyDbSingleton().create_all()
|
45
|
+
|
46
|
+
parent1 = Parent.get(name="parent1")
|
47
|
+
if parent1 is None:
|
48
|
+
parent1 = Parent(name="parent1")
|
49
|
+
parent1.save()
|
50
|
+
|
51
|
+
child1 = Child.get(name="child1")
|
52
|
+
if child1 is None:
|
53
|
+
child1 = Child(name="child1", parent_id=parent1.id)
|
54
|
+
child1.save()
|
55
|
+
|
56
|
+
child2 = Child.get(name="child2")
|
57
|
+
if child2 is None:
|
58
|
+
child2 = Child(name="child2", parent_id=parent1.id)
|
59
|
+
child2.save()
|
60
|
+
|
61
|
+
child3 = Child.get(name="child3")
|
62
|
+
if child3 is None:
|
63
|
+
child3 = Child(name="child3", parent_id=parent1.id)
|
64
|
+
child3.save()
|
65
|
+
|
66
|
+
parent2 = Parent.get(name="parent2")
|
67
|
+
if parent2 is None:
|
68
|
+
parent2 = Parent(name="parent2")
|
69
|
+
parent2.save()
|
70
|
+
|
71
|
+
child4 = Child.get(name="child4")
|
72
|
+
if child4 is None:
|
73
|
+
child4 = Child(name="child4", parent_id=parent2.id)
|
74
|
+
child4.save()
|
75
|
+
|
76
|
+
child5 = Child.get(name="child5")
|
77
|
+
if child5 is None:
|
78
|
+
child5 = Child(name="child5", parent_id=parent2.id)
|
79
|
+
child5.save()
|
80
|
+
|
81
|
+
child6 = Child.get(name="child6")
|
82
|
+
if child6 is None:
|
83
|
+
child6 = Child(name="child6", parent_id=parent2.id)
|
84
|
+
child6.save()
|
85
|
+
|
86
|
+
Parent.delete_all() # Should raise an IntegrityError --> FOREIGN KEY constraint failed
|
87
|
+
parent2.delete() # Should raise an IntegrityError --> FOREIGN KEY constraint failed
|
88
|
+
|
89
|
+
print()
|
@@ -1,11 +1,13 @@
|
|
1
|
+
import warnings
|
1
2
|
from typing import Any, Optional, Callable, Union, TYPE_CHECKING
|
2
3
|
|
3
4
|
from sqlalchemy import inspect
|
4
5
|
from sqlalchemy.sql import ColumnExpressionArgument
|
5
|
-
from sqlalchemy.orm import Session, QueryableAttribute
|
6
|
+
from sqlalchemy.orm import Session, QueryableAttribute
|
6
7
|
from sqlalchemy.orm.exc import DetachedInstanceError
|
7
8
|
|
8
9
|
from wiederverwendbar.default import Default
|
10
|
+
from wiederverwendbar.functions.get_pretty_str import get_pretty_str
|
9
11
|
from wiederverwendbar.sqlalchemy.raise_has_not_attr import raise_has_not_attr
|
10
12
|
|
11
13
|
if TYPE_CHECKING:
|
@@ -141,7 +143,18 @@ class Base:
|
|
141
143
|
super().__init__(*args, **kwargs)
|
142
144
|
|
143
145
|
def __str__(self):
|
144
|
-
|
146
|
+
out = f"{self.__class__.__name__}("
|
147
|
+
for attr_name in self.__str_columns__:
|
148
|
+
if type(attr_name) is tuple:
|
149
|
+
attr_view_name = attr_name[0]
|
150
|
+
attr_name = attr_name[1]
|
151
|
+
else:
|
152
|
+
attr_view_name = attr_name
|
153
|
+
if not hasattr(self, attr_name):
|
154
|
+
warnings.warn(f"Attribute '{attr_name}' is not set for {self}.")
|
155
|
+
out += f"{attr_view_name}={get_pretty_str(getattr(self, attr_name))}, "
|
156
|
+
out = out[:-2] + ")"
|
157
|
+
return out
|
145
158
|
|
146
159
|
def __repr__(self):
|
147
160
|
return self.__str__()
|
@@ -399,3 +412,19 @@ class Base:
|
|
399
412
|
session.commit()
|
400
413
|
|
401
414
|
self.session_close(session_created=session_created, session=session)
|
415
|
+
|
416
|
+
@classmethod
|
417
|
+
def delete_all(cls,
|
418
|
+
*criterion: Union[ColumnExpressionArgument[bool], bool],
|
419
|
+
session: Optional[Session] = None,
|
420
|
+
**kwargs: Any) -> None:
|
421
|
+
session_created, session = cls.session(session=session)
|
422
|
+
|
423
|
+
# delete rows
|
424
|
+
if criterion:
|
425
|
+
session.query(cls).filter(*criterion, **kwargs).delete()
|
426
|
+
else:
|
427
|
+
session.query(cls).filter_by(**kwargs).delete()
|
428
|
+
session.commit()
|
429
|
+
|
430
|
+
cls.session_close(session_created=session_created, session=session)
|
@@ -0,0 +1,278 @@
|
|
1
|
+
import inspect
|
2
|
+
import logging
|
3
|
+
import sqlite3
|
4
|
+
from ipaddress import IPv4Address
|
5
|
+
from pathlib import Path
|
6
|
+
from typing import Any, Optional, Union, Sequence, Callable
|
7
|
+
|
8
|
+
from sqlalchemy import create_engine, Table, event
|
9
|
+
from sqlalchemy.orm import sessionmaker, declarative_base, DeclarativeMeta as _DeclarativeMeta, Session
|
10
|
+
from sqlalchemy.ext.declarative import declarative_base
|
11
|
+
|
12
|
+
from wiederverwendbar.sqlalchemy.settings import SqlalchemySettings
|
13
|
+
|
14
|
+
logger = logging.getLogger(__name__)
|
15
|
+
|
16
|
+
|
17
|
+
class DeclarativeMeta(_DeclarativeMeta):
|
18
|
+
def __init__(cls, classname: Any, bases: Any, dict_: Any, **kw: Any) -> None:
|
19
|
+
db = None
|
20
|
+
for base in bases:
|
21
|
+
if hasattr(base, "db"):
|
22
|
+
db = base.db
|
23
|
+
if db is None:
|
24
|
+
stack = inspect.stack()
|
25
|
+
for frame in stack:
|
26
|
+
if frame.function == "__init__":
|
27
|
+
db = frame.frame.f_locals.get("self", None)
|
28
|
+
if isinstance(db, SqlalchemyDb):
|
29
|
+
break
|
30
|
+
super().__init__(classname=classname, bases=bases, dict_=dict_, **kw)
|
31
|
+
|
32
|
+
cls.db: SqlalchemyDb = db
|
33
|
+
|
34
|
+
|
35
|
+
class SqlalchemyDb:
|
36
|
+
def __init__(self,
|
37
|
+
file: Optional[Path] = None,
|
38
|
+
host: Union[None, IPv4Address, str] = None,
|
39
|
+
port: Optional[int] = None,
|
40
|
+
protocol: Optional[str] = None,
|
41
|
+
name: Optional[str] = None,
|
42
|
+
username: Optional[str] = None,
|
43
|
+
password: Optional[str] = None,
|
44
|
+
echo: Optional[bool] = None,
|
45
|
+
test_on_startup: Optional[bool] = None,
|
46
|
+
sqlite_check_if_file_exist: Optional[bool] = None,
|
47
|
+
sqlite_handle_foreign_keys: Optional[bool] = None,
|
48
|
+
settings: Optional[SqlalchemySettings] = None):
|
49
|
+
"""
|
50
|
+
Create a new Sqlalchemy Database
|
51
|
+
|
52
|
+
:param host: Host to connect to database
|
53
|
+
:param port: Port to connect to database
|
54
|
+
:param protocol: Protocol to connect to database
|
55
|
+
:param name: Name of the database
|
56
|
+
:param username: User to connect to database
|
57
|
+
:param password: Password to connect to database
|
58
|
+
:param echo: Echo SQL queries to console
|
59
|
+
:param test_on_startup: Test the database connection on startup.
|
60
|
+
:param sqlite_check_if_file_exist: Check if SQLite file exists before connecting to it.
|
61
|
+
:param sqlite_handle_foreign_keys: Enable SQLite Foreign Keys
|
62
|
+
:param settings: Sqlalchemy Settings
|
63
|
+
"""
|
64
|
+
|
65
|
+
self._settings: SqlalchemySettings = settings or SqlalchemySettings()
|
66
|
+
self._file: Optional[Path] = file or self.settings.db_file
|
67
|
+
self._host: Union[IPv4Address, str, None] = host or self.settings.db_host
|
68
|
+
self._port: Optional[int] = port or self.settings.db_port
|
69
|
+
self._protocol: Optional[str] = protocol or self.settings.db_protocol
|
70
|
+
self._name: Optional[str] = name or self.settings.db_name
|
71
|
+
self._username: Optional[str] = username or self.settings.db_username
|
72
|
+
self._password: Optional[str] = password or self.settings.db_password
|
73
|
+
self._echo: bool = echo or self.settings.db_echo
|
74
|
+
self._test_on_startup: bool = test_on_startup or self.settings.db_test_on_startup
|
75
|
+
self._sqlite_check_if_file_exist: bool = sqlite_check_if_file_exist or self.settings.db_sqlite_check_if_file_exist
|
76
|
+
self._sqlite_handle_foreign_keys: bool = sqlite_handle_foreign_keys or self.settings.db_sqlite_handle_foreign_keys
|
77
|
+
|
78
|
+
logger.debug(f"Create {self}")
|
79
|
+
|
80
|
+
self.engine = create_engine(self.connection_string, echo=self.echo)
|
81
|
+
if self.protocol == "sqlite":
|
82
|
+
if self.sqlite_check_if_file_exist:
|
83
|
+
self.listen("connect", self._sqlite_check_if_file_exist_func)
|
84
|
+
if self.sqlite_handle_foreign_keys:
|
85
|
+
self.listen("connect", self._sqlite_handle_foreign_keys_func)
|
86
|
+
self._session_maker = sessionmaker(bind=self.engine)
|
87
|
+
self._Base: DeclarativeMeta = declarative_base(metaclass=DeclarativeMeta)
|
88
|
+
self.session_maker.configure(binds={self._Base: self.engine})
|
89
|
+
|
90
|
+
if self.test_on_startup:
|
91
|
+
self.test()
|
92
|
+
|
93
|
+
def __str__(self):
|
94
|
+
return f"{self.__class__.__name__}({self.connection_string_printable})"
|
95
|
+
|
96
|
+
@property
|
97
|
+
def settings(self) -> SqlalchemySettings:
|
98
|
+
return self._settings
|
99
|
+
|
100
|
+
@property
|
101
|
+
def file(self) -> Optional[Path]:
|
102
|
+
return self._file
|
103
|
+
|
104
|
+
@property
|
105
|
+
def host(self) -> Union[IPv4Address, str, None]:
|
106
|
+
return self._host
|
107
|
+
|
108
|
+
@property
|
109
|
+
def port(self) -> Optional[int]:
|
110
|
+
return self._port
|
111
|
+
|
112
|
+
@property
|
113
|
+
def protocol(self) -> Optional[str]:
|
114
|
+
return self._protocol
|
115
|
+
|
116
|
+
@property
|
117
|
+
def name(self) -> Optional[str]:
|
118
|
+
return self._name
|
119
|
+
|
120
|
+
@property
|
121
|
+
def username(self) -> Optional[str]:
|
122
|
+
return self._username
|
123
|
+
|
124
|
+
@property
|
125
|
+
def password(self) -> Optional[str]:
|
126
|
+
return self._password
|
127
|
+
|
128
|
+
@property
|
129
|
+
def echo(self) -> bool:
|
130
|
+
return self._echo
|
131
|
+
|
132
|
+
@property
|
133
|
+
def test_on_startup(self) -> bool:
|
134
|
+
return self._test_on_startup
|
135
|
+
|
136
|
+
@property
|
137
|
+
def sqlite_check_if_file_exist(self) -> bool:
|
138
|
+
return self._sqlite_check_if_file_exist
|
139
|
+
|
140
|
+
@property
|
141
|
+
def sqlite_handle_foreign_keys(self) -> bool:
|
142
|
+
return self._sqlite_handle_foreign_keys
|
143
|
+
|
144
|
+
@property
|
145
|
+
def session_maker(self) -> sessionmaker:
|
146
|
+
return self._session_maker
|
147
|
+
|
148
|
+
# noinspection PyPep8Naming
|
149
|
+
@property
|
150
|
+
def Base(self) -> Any:
|
151
|
+
return self._Base
|
152
|
+
|
153
|
+
def get_connection_string(self, printable: bool = False) -> str:
|
154
|
+
"""
|
155
|
+
Get the Connection String
|
156
|
+
|
157
|
+
:param printable: If True, the password will be hidden
|
158
|
+
:return: str
|
159
|
+
"""
|
160
|
+
|
161
|
+
connection_string = f"{self.protocol}://"
|
162
|
+
if self.protocol == "sqlite":
|
163
|
+
if self.file is not None:
|
164
|
+
connection_string += f"/{self.file}"
|
165
|
+
else:
|
166
|
+
if self.username is not None:
|
167
|
+
connection_string += f"{self.username}"
|
168
|
+
if self.password is not None:
|
169
|
+
connection_string += ":"
|
170
|
+
if printable:
|
171
|
+
connection_string += "***"
|
172
|
+
else:
|
173
|
+
connection_string += self.password
|
174
|
+
if self.host is None:
|
175
|
+
raise RuntimeError(f"No host specified for {self}")
|
176
|
+
connection_string += f"@{self.host}"
|
177
|
+
if self.port is None:
|
178
|
+
raise RuntimeError(f"No port specified for {self}")
|
179
|
+
connection_string += f":{self.port}"
|
180
|
+
if self.name is None:
|
181
|
+
raise RuntimeError(f"No name specified for {self}")
|
182
|
+
connection_string += f"/{self.name}"
|
183
|
+
return connection_string
|
184
|
+
|
185
|
+
@property
|
186
|
+
def connection_string(self) -> str:
|
187
|
+
"""
|
188
|
+
Get the Connection String
|
189
|
+
|
190
|
+
:return: str
|
191
|
+
"""
|
192
|
+
|
193
|
+
return self.get_connection_string()
|
194
|
+
|
195
|
+
@property
|
196
|
+
def connection_string_printable(self) -> str:
|
197
|
+
"""
|
198
|
+
Get the Connection String with Password hidden
|
199
|
+
|
200
|
+
:return: str
|
201
|
+
"""
|
202
|
+
|
203
|
+
return self.get_connection_string(printable=True)
|
204
|
+
|
205
|
+
def test(self):
|
206
|
+
self.engine.connect()
|
207
|
+
print()
|
208
|
+
|
209
|
+
def create_all(self,
|
210
|
+
tables: Optional[Sequence[Table]] = None,
|
211
|
+
check_first: bool = True) -> None:
|
212
|
+
"""
|
213
|
+
Create all Tables
|
214
|
+
|
215
|
+
:param tables: List of Tables to create. If None, all Tables will be created.
|
216
|
+
:param check_first: Check if Tables exist before creating them.
|
217
|
+
:return: None
|
218
|
+
"""
|
219
|
+
|
220
|
+
logger.debug(f"Create all for {self}")
|
221
|
+
self.Base.metadata.create_all(bind=self.engine, tables=tables, checkfirst=check_first)
|
222
|
+
|
223
|
+
def session(self) -> Session:
|
224
|
+
"""
|
225
|
+
Create a new Session
|
226
|
+
|
227
|
+
:return: Session
|
228
|
+
"""
|
229
|
+
|
230
|
+
logger.debug(f"Create Session for {self}")
|
231
|
+
return self.session_maker()
|
232
|
+
|
233
|
+
def listen(self,
|
234
|
+
identifier: str,
|
235
|
+
func: Callable[..., Any],
|
236
|
+
*args: Any,
|
237
|
+
**kwargs: Any) -> None:
|
238
|
+
"""
|
239
|
+
Register a listener function for the engine.
|
240
|
+
|
241
|
+
:param identifier: String name of the event.
|
242
|
+
:param func: Callable function.
|
243
|
+
:return: None
|
244
|
+
|
245
|
+
.. Seealso::
|
246
|
+
sqlalchemy.event.api.listen for more.
|
247
|
+
"""
|
248
|
+
|
249
|
+
event.listen(self.engine, identifier, func, *args, **kwargs)
|
250
|
+
|
251
|
+
def listens_for(self,
|
252
|
+
identifier: str,
|
253
|
+
*args: Any,
|
254
|
+
**kw: Any) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
|
255
|
+
"""
|
256
|
+
Decorate a function as a listener for the engine.
|
257
|
+
|
258
|
+
:param identifier: String name of the event.
|
259
|
+
:return: Callable[[Callable[..., Any]], Callable[..., Any]]
|
260
|
+
|
261
|
+
.. Seealso::
|
262
|
+
sqlalchemy.event.api.listens_for for more.
|
263
|
+
"""
|
264
|
+
|
265
|
+
return event.listens_for(self.engine, identifier, *args, **kw)
|
266
|
+
|
267
|
+
def _sqlite_check_if_file_exist_func(self, connection, _connection_record):
|
268
|
+
if self.file is not None:
|
269
|
+
if not self.file.is_file():
|
270
|
+
raise FileNotFoundError(f"Database file does not exist: {self.file}")
|
271
|
+
|
272
|
+
# noinspection PyMethodMayBeStatic
|
273
|
+
def _sqlite_handle_foreign_keys_func(self, connection, _connection_record):
|
274
|
+
if not isinstance(connection, sqlite3.Connection):
|
275
|
+
raise RuntimeError(f"Connection is not a sqlite3.Connection: {connection}")
|
276
|
+
cursor = connection.cursor()
|
277
|
+
cursor.execute("PRAGMA foreign_keys=ON")
|
278
|
+
cursor.close()
|
{wiederverwendbar-0.8.3 → wiederverwendbar-0.8.5}/src/wiederverwendbar/sqlalchemy/settings.py
RENAMED
@@ -34,3 +34,12 @@ class SqlalchemySettings(PrintableSettings):
|
|
34
34
|
db_echo: bool = Field(default=False,
|
35
35
|
title="Database echo.",
|
36
36
|
description="Echo SQL queries to console")
|
37
|
+
db_test_on_startup: bool = Field(default=True,
|
38
|
+
title="Test Database on Startup",
|
39
|
+
description="Test database connection on startup")
|
40
|
+
db_sqlite_check_if_file_exist: bool = Field(default=True,
|
41
|
+
title="Database SQLite Check If File Exist",
|
42
|
+
description="Check if file exists in SQLite")
|
43
|
+
db_sqlite_handle_foreign_keys: bool = Field(default=True,
|
44
|
+
title="Database SQLite Handle Foreign Keys",
|
45
|
+
description="Handle foreign keys in SQLite")
|
@@ -1,31 +0,0 @@
|
|
1
|
-
from pathlib import Path
|
2
|
-
|
3
|
-
from sqlalchemy import Column, Text, Integer
|
4
|
-
|
5
|
-
from wiederverwendbar.logger import LoggerSingleton, LoggerSettings
|
6
|
-
from wiederverwendbar.sqlalchemy import Base, SqlalchemySettings, SqlalchemyDbSingleton
|
7
|
-
|
8
|
-
LoggerSingleton(name="test", settings=LoggerSettings(log_level=LoggerSettings.LogLevels.DEBUG), init=True)
|
9
|
-
|
10
|
-
|
11
|
-
class MyBase(Base, SqlalchemyDbSingleton(settings=SqlalchemySettings(db_file=Path("test.db")), init=True).Base):
|
12
|
-
__abstract__ = True
|
13
|
-
|
14
|
-
|
15
|
-
class MyTable(MyBase):
|
16
|
-
__tablename__ = "my_table"
|
17
|
-
__str_columns__: list[str] = ["name"]
|
18
|
-
|
19
|
-
name = Column(Text(50), primary_key=True)
|
20
|
-
value = Column(Integer)
|
21
|
-
|
22
|
-
|
23
|
-
if __name__ == '__main__':
|
24
|
-
SqlalchemyDbSingleton().create_all()
|
25
|
-
|
26
|
-
my_table = MyTable(name="test", value=1)
|
27
|
-
|
28
|
-
d = my_table.as_dict()
|
29
|
-
my_table.save()
|
30
|
-
|
31
|
-
print()
|