velocity-python 0.1.9__tar.gz → 0.1.11__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.
- {velocity_python-0.1.9/src/velocity_python.egg-info → velocity_python-0.1.11}/PKG-INFO +1 -1
- {velocity_python-0.1.9 → velocity_python-0.1.11}/pyproject.toml +4 -1
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/__init__.py +1 -1
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/core/row.py +65 -4
- velocity_python-0.1.11/src/velocity/db/migrations.py +586 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11/src/velocity_python.egg-info}/PKG-INFO +1 -1
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity_python.egg-info/SOURCES.txt +4 -0
- velocity_python-0.1.11/src/velocity_python.egg-info/entry_points.txt +2 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_row_batch_update.py +2 -0
- velocity_python-0.1.11/tests/test_row_dirty_tracking.py +193 -0
- velocity_python-0.1.11/tests/test_schema_migrations.py +922 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/LICENSE +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/README.md +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/setup.cfg +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/app/__init__.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/app/formbuilder/__init__.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/app/formbuilder/reshaper.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/app/invoices.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/app/orders.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/app/payments.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/app/purchase_orders.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/app/tests/__init__.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/app/tests/test_email_processing.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/app/tests/test_payment_profile_sorting.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/app/tests/test_spreadsheet_functions.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/app/validators/__init__.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/app/validators/formbuilder_template.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/aws/__init__.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/aws/amplify.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/aws/amplify_build.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/aws/handlers/__init__.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/aws/handlers/base_handler.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/aws/handlers/context.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/aws/handlers/context_factory.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/aws/handlers/exceptions.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/aws/handlers/lambda_handler.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/aws/handlers/mixins/__init__.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/aws/handlers/mixins/data_service.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/aws/handlers/mixins/web_handler.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/aws/handlers/perf.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/aws/handlers/response.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/aws/handlers/sqs_handler.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/aws/tests/__init__.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/aws/tests/test_base_handler_error_response.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/aws/tests/test_lambda_handler_json_serialization.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/aws/tests/test_response.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/__init__.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/core/__init__.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/core/async_support.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/core/column.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/core/database.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/core/decorators.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/core/engine.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/core/result.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/core/sequence.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/core/table.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/core/transaction.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/core/view.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/exceptions.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/servers/__init__.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/servers/base/__init__.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/servers/base/initializer.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/servers/base/operators.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/servers/base/sql.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/servers/base/types.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/servers/mysql/__init__.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/servers/mysql/operators.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/servers/mysql/reserved.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/servers/mysql/sql.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/servers/mysql/types.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/servers/postgres/__init__.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/servers/postgres/operators.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/servers/postgres/reserved.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/servers/postgres/sql.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/servers/postgres/types.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/servers/sqlite/__init__.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/servers/sqlite/operators.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/servers/sqlite/reserved.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/servers/sqlite/sql.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/servers/sqlite/types.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/servers/sqlserver/__init__.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/servers/sqlserver/operators.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/servers/sqlserver/reserved.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/servers/sqlserver/sql.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/servers/sqlserver/types.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/servers/tablehelper.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/__init__.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/common_db_test.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/postgres/__init__.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/postgres/common.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/postgres/test_column.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/postgres/test_connections.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/postgres/test_database.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/postgres/test_engine.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/postgres/test_general_usage.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/postgres/test_imports.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/postgres/test_result.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/postgres/test_row.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/postgres/test_row_comprehensive.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/postgres/test_schema_locking.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/postgres/test_schema_locking_unit.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/postgres/test_sequence.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/postgres/test_sql_comprehensive.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/postgres/test_table.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/postgres/test_table_comprehensive.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/postgres/test_transaction.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/sql/__init__.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/sql/common.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/sql/test_postgres_select_advanced.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/sql/test_postgres_select_variances.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/test_cursor_rowcount_fix.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/test_db_utils.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/test_postgres.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/test_postgres_unchanged.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/test_process_error_robustness.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/test_result_caching.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/test_result_sql_aware.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/test_row_get_missing_column.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/test_schema_locking_initializers.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/test_schema_locking_simple.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/test_sql_builder.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/test_tablehelper.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/tests/test_view_helper.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/db/utils.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/logging.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/misc/__init__.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/misc/conv/__init__.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/misc/conv/iconv.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/misc/conv/oconv.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/misc/db.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/misc/export.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/misc/format.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/misc/mail.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/misc/merge.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/misc/tests/__init__.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/misc/tests/test_db.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/misc/tests/test_fix.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/misc/tests/test_format.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/misc/tests/test_iconv.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/misc/tests/test_merge.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/misc/tests/test_oconv.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/misc/tests/test_original_error.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/misc/tests/test_timer.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/misc/timer.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/misc/tools.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/payment/__init__.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/payment/authorizenet_adapter.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/payment/base_adapter.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/payment/braintree_adapter.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/payment/charge_rules.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/payment/demo_profiles.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/payment/profiles.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/payment/router.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity/payment/stripe_adapter.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity_python.egg-info/dependency_links.txt +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity_python.egg-info/requires.txt +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/src/velocity_python.egg-info/top_level.txt +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_amplify_build.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_async_support.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_batch_operations.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_concurrency_safety.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_connection_pool.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_connection_resilience.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_decorators.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_formbuilder_reshaper.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_formbuilder_template_validator.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_iconv_money_to_cents.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_lambda_handler.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_lambda_handler_auth.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_mixins_import.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_n_plus_one.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_observability.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_payment_braintree_adapter.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_payment_demo_profiles.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_payment_profiles.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_payment_router.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_payment_stripe_adapter.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_prepared_statements.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_psycopg3_upgrade.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_query_cache.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_row_cache_staleness.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_security_hardening.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_sqs_per_record_transactions.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_sys_modified_count_postgres_demo.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_table_alter.py +0 -0
- {velocity_python-0.1.9 → velocity_python-0.1.11}/tests/test_where_clause_validation.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "velocity-python"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.11"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name="Velocity Team", email="info@codeclubs.org" },
|
|
10
10
|
]
|
|
@@ -29,6 +29,9 @@ dependencies = [
|
|
|
29
29
|
"sqlparse>=0.5.0"
|
|
30
30
|
]
|
|
31
31
|
|
|
32
|
+
[project.scripts]
|
|
33
|
+
velocity = "velocity.db.migrations:cli"
|
|
34
|
+
|
|
32
35
|
[project.urls]
|
|
33
36
|
Homepage = "https://codeclubs.org/projects/velocity"
|
|
34
37
|
Documentation = "https://codeclubs.org/projects/velocity"
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import pprint
|
|
2
2
|
import time as _time
|
|
3
|
-
import warnings
|
|
4
3
|
from collections.abc import MutableMapping
|
|
5
4
|
from velocity.db.exceptions import DbColumnMissingError
|
|
6
5
|
|
|
@@ -9,7 +8,7 @@ from velocity.db.exceptions import DbColumnMissingError
|
|
|
9
8
|
# intercepted by __getattr__ / __setattr__.
|
|
10
9
|
_INTERNAL_ATTRS = frozenset({
|
|
11
10
|
"table", "pk", "_cache", "_column_set", "_batching", "_pending",
|
|
12
|
-
"_cache_ttl", "_cache_time", "_no_cache",
|
|
11
|
+
"_cache_ttl", "_cache_time", "_no_cache", "_dirty_tracking", "_dirty",
|
|
13
12
|
})
|
|
14
13
|
|
|
15
14
|
|
|
@@ -25,7 +24,7 @@ class Row(MutableMapping):
|
|
|
25
24
|
write-through (immediate UPDATE) and also update the local cache.
|
|
26
25
|
"""
|
|
27
26
|
|
|
28
|
-
def __init__(self, table, key, lock=None, cache_ttl=None, no_cache=False):
|
|
27
|
+
def __init__(self, table, key, lock=None, cache_ttl=None, no_cache=False, dirty_tracking=False):
|
|
29
28
|
if isinstance(table, str):
|
|
30
29
|
raise Exception("Table parameter must be a `table` instance.")
|
|
31
30
|
object.__setattr__(self, "table", table)
|
|
@@ -48,6 +47,8 @@ class Row(MutableMapping):
|
|
|
48
47
|
object.__setattr__(self, "_cache_ttl", cache_ttl)
|
|
49
48
|
object.__setattr__(self, "_cache_time", None)
|
|
50
49
|
object.__setattr__(self, "_no_cache", no_cache)
|
|
50
|
+
object.__setattr__(self, "_dirty_tracking", dirty_tracking)
|
|
51
|
+
object.__setattr__(self, "_dirty", {})
|
|
51
52
|
if lock:
|
|
52
53
|
self.lock()
|
|
53
54
|
|
|
@@ -78,6 +79,8 @@ class Row(MutableMapping):
|
|
|
78
79
|
object.__setattr__(row, "_cache_ttl", None)
|
|
79
80
|
object.__setattr__(row, "_cache_time", _time.monotonic())
|
|
80
81
|
object.__setattr__(row, "_no_cache", False)
|
|
82
|
+
object.__setattr__(row, "_dirty_tracking", False)
|
|
83
|
+
object.__setattr__(row, "_dirty", {})
|
|
81
84
|
return row
|
|
82
85
|
|
|
83
86
|
# ------------------------------------------------------------------
|
|
@@ -144,6 +147,13 @@ class Row(MutableMapping):
|
|
|
144
147
|
self._cache[key] = val
|
|
145
148
|
object.__setattr__(self, "_column_set", None)
|
|
146
149
|
return
|
|
150
|
+
if self._dirty_tracking:
|
|
151
|
+
self._dirty[key] = val
|
|
152
|
+
# Update local cache optimistically so reads see the dirty value
|
|
153
|
+
if self._cache is not None:
|
|
154
|
+
self._cache[key] = val
|
|
155
|
+
object.__setattr__(self, "_column_set", None)
|
|
156
|
+
return
|
|
147
157
|
self.table.update_or_insert({key: val}, pk=self.pk)
|
|
148
158
|
# Invalidate cache so trigger-computed columns are re-fetched
|
|
149
159
|
object.__setattr__(self, "_cache", None)
|
|
@@ -394,6 +404,55 @@ class Row(MutableMapping):
|
|
|
394
404
|
"""
|
|
395
405
|
return _BatchContext(self)
|
|
396
406
|
|
|
407
|
+
def save(self):
|
|
408
|
+
"""Flush accumulated dirty-tracking changes to the database.
|
|
409
|
+
|
|
410
|
+
When ``dirty_tracking=True``, assignments to the row accumulate
|
|
411
|
+
in memory instead of writing through immediately. Call
|
|
412
|
+
``.save()`` to flush them all in a single UPDATE::
|
|
413
|
+
|
|
414
|
+
row = Row(table, 1, dirty_tracking=True)
|
|
415
|
+
row["name"] = "John"
|
|
416
|
+
row["email"] = "john@example.com"
|
|
417
|
+
row.save() # Single UPDATE with both columns
|
|
418
|
+
|
|
419
|
+
Returns ``self`` for chaining.
|
|
420
|
+
|
|
421
|
+
Raises:
|
|
422
|
+
RuntimeError: If dirty tracking is not enabled on this row.
|
|
423
|
+
"""
|
|
424
|
+
if not self._dirty_tracking:
|
|
425
|
+
raise RuntimeError(
|
|
426
|
+
"save() requires dirty_tracking=True. "
|
|
427
|
+
"Use Row(table, key, dirty_tracking=True) or row.update({...})."
|
|
428
|
+
)
|
|
429
|
+
dirty = self._dirty
|
|
430
|
+
object.__setattr__(self, "_dirty", {})
|
|
431
|
+
if dirty:
|
|
432
|
+
self.table.update_or_insert(dirty, pk=self.pk)
|
|
433
|
+
# Invalidate cache so trigger-computed columns are re-fetched
|
|
434
|
+
object.__setattr__(self, "_cache", None)
|
|
435
|
+
object.__setattr__(self, "_column_set", None)
|
|
436
|
+
return self
|
|
437
|
+
|
|
438
|
+
@property
|
|
439
|
+
def is_dirty(self):
|
|
440
|
+
"""Return True if there are unsaved dirty-tracking changes."""
|
|
441
|
+
return bool(self._dirty)
|
|
442
|
+
|
|
443
|
+
def discard(self):
|
|
444
|
+
"""Discard accumulated dirty-tracking changes without writing to DB.
|
|
445
|
+
|
|
446
|
+
Also invalidates the cache so the next read re-fetches from the
|
|
447
|
+
database, undoing any optimistic cache updates.
|
|
448
|
+
|
|
449
|
+
Returns ``self`` for chaining.
|
|
450
|
+
"""
|
|
451
|
+
object.__setattr__(self, "_dirty", {})
|
|
452
|
+
object.__setattr__(self, "_cache", None)
|
|
453
|
+
object.__setattr__(self, "_column_set", None)
|
|
454
|
+
return self
|
|
455
|
+
|
|
397
456
|
def touch(self):
|
|
398
457
|
"""
|
|
399
458
|
Update sys_modified to current timestamp.
|
|
@@ -473,5 +532,7 @@ class _BatchContext:
|
|
|
473
532
|
|
|
474
533
|
if pending:
|
|
475
534
|
row.table.update_or_insert(pending, pk=row.pk)
|
|
476
|
-
#
|
|
535
|
+
# Invalidate cache so trigger-computed columns are re-fetched
|
|
536
|
+
object.__setattr__(row, "_cache", None)
|
|
537
|
+
object.__setattr__(row, "_column_set", None)
|
|
477
538
|
return False
|