hare-orm 0.9.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hare/__init__.py +47 -0
- hare/__main__.py +8 -0
- hare/classes/__init__.py +1 -0
- hare/classes/class_path.py +50 -0
- hare/classes/class_property.py +18 -0
- hare/classes/comparable_values.py +113 -0
- hare/classes/constants.py +11 -0
- hare/classes/declared_subclass.py +26 -0
- hare/classes/lazy_exports.py +56 -0
- hare/classes/shown_value_repr.py +21 -0
- hare/classes/value_descriptions.py +81 -0
- hare/cli/__init__.py +3 -0
- hare/cli/__main__.py +7 -0
- hare/cli/arg_parser_builder.py +344 -0
- hare/cli/commands/__init__.py +0 -0
- hare/cli/commands/database_shell_commands.py +56 -0
- hare/cli/commands/distributed_recovery_commands.py +86 -0
- hare/cli/commands/interactive_rename_questions.py +30 -0
- hare/cli/commands/migration_commands.py +579 -0
- hare/cli/commands/schema_commands.py +123 -0
- hare/cli/commands/stub_commands.py +52 -0
- hare/cli/config_locator.py +37 -0
- hare/cli/constants.py +24 -0
- hare/cli/context/__init__.py +9 -0
- hare/cli/context/cli_context.py +17 -0
- hare/cli/context/command_context.py +108 -0
- hare/cli/exceptions.py +9 -0
- hare/cli/hare_cli.py +111 -0
- hare/cli/output/__init__.py +1 -0
- hare/cli/output/output_formatter.py +145 -0
- hare/cli/output/terminal_colors.py +89 -0
- hare/cli/plugins/__init__.py +16 -0
- hare/cli/plugins/cli_command.py +43 -0
- hare/cli/plugins/cli_command_registry.py +144 -0
- hare/cli/plugins/loaded_cli_command.py +13 -0
- hare/cli/shell_launcher.py +95 -0
- hare/contrib/__init__.py +0 -0
- hare/contrib/application_lifecycle.py +157 -0
- hare/contrib/factories/__init__.py +39 -0
- hare/contrib/factories/constants.py +21 -0
- hare/contrib/factories/factory_reference.py +27 -0
- hare/contrib/factories/field_declarations/__init__.py +1 -0
- hare/contrib/factories/field_declarations/declaration.py +19 -0
- hare/contrib/factories/field_declarations/faker.py +49 -0
- hare/contrib/factories/field_declarations/iterator.py +36 -0
- hare/contrib/factories/field_declarations/lazy_attribute.py +35 -0
- hare/contrib/factories/field_declarations/lazy_function.py +22 -0
- hare/contrib/factories/field_declarations/many_to_many.py +40 -0
- hare/contrib/factories/field_declarations/post_declaration.py +22 -0
- hare/contrib/factories/field_declarations/related_factory.py +37 -0
- hare/contrib/factories/field_declarations/sequence.py +22 -0
- hare/contrib/factories/field_declarations/sub_factory.py +30 -0
- hare/contrib/factories/model_factory.py +284 -0
- hare/contrib/factories/trait.py +23 -0
- hare/contrib/frameworks/__init__.py +14 -0
- hare/contrib/frameworks/constants.py +45 -0
- hare/contrib/frameworks/error_answers.py +93 -0
- hare/contrib/frameworks/exceptions.py +19 -0
- hare/contrib/frameworks/fastapi/__init__.py +12 -0
- hare/contrib/frameworks/fastapi/constants.py +4 -0
- hare/contrib/frameworks/fastapi/hare_exception_handlers.py +103 -0
- hare/contrib/frameworks/fastapi/hare_fast_api.py +139 -0
- hare/contrib/frameworks/fastapi/middleware/__init__.py +7 -0
- hare/contrib/frameworks/fastapi/middleware/request_state_reset_middleware.py +27 -0
- hare/contrib/frameworks/fastapi/middleware/transaction_failing_handler.py +31 -0
- hare/contrib/frameworks/fastapi/middleware/transaction_middleware.py +72 -0
- hare/contrib/frameworks/fastapi/request_query_dependency.py +88 -0
- hare/contrib/frameworks/hare_lifecycle.py +50 -0
- hare/contrib/frameworks/health_routes.py +101 -0
- hare/contrib/frameworks/litestar/__init__.py +14 -0
- hare/contrib/frameworks/litestar/constants.py +18 -0
- hare/contrib/frameworks/litestar/hare_dto.py +194 -0
- hare/contrib/frameworks/litestar/hare_exception_handlers.py +77 -0
- hare/contrib/frameworks/litestar/hare_plugin.py +181 -0
- hare/contrib/frameworks/litestar/hare_transfer_function_factory.py +38 -0
- hare/contrib/frameworks/litestar/middleware/__init__.py +7 -0
- hare/contrib/frameworks/litestar/middleware/request_state_reset_middleware.py +23 -0
- hare/contrib/frameworks/litestar/middleware/transaction_middleware.py +35 -0
- hare/contrib/frameworks/litestar/request_query_di_plugin.py +96 -0
- hare/contrib/frameworks/pages/__init__.py +22 -0
- hare/contrib/frameworks/pages/cursor_page_schema.py +25 -0
- hare/contrib/frameworks/pages/page_schema.py +25 -0
- hare/contrib/frameworks/pages/scroll_page_schema.py +23 -0
- hare/contrib/frameworks/parameter_annotation.py +110 -0
- hare/contrib/frameworks/request_state.py +16 -0
- hare/contrib/frameworks/request_transaction.py +186 -0
- hare/contrib/frameworks/robyn/__init__.py +13 -0
- hare/contrib/frameworks/robyn/application/__init__.py +11 -0
- hare/contrib/frameworks/robyn/application/hare_robyn.py +199 -0
- hare/contrib/frameworks/robyn/application/hare_sub_router.py +50 -0
- hare/contrib/frameworks/robyn/constants.py +32 -0
- hare/contrib/frameworks/robyn/hare_exception_handlers.py +128 -0
- hare/contrib/frameworks/robyn/hare_open_api.py +91 -0
- hare/contrib/frameworks/robyn/route_handler.py +198 -0
- hare/contrib/mypy/__init__.py +11 -0
- hare/contrib/mypy/annotation_types.py +170 -0
- hare/contrib/mypy/constants.py +83 -0
- hare/contrib/mypy/enums.py +18 -0
- hare/contrib/mypy/field_names_check.py +222 -0
- hare/contrib/mypy/filter_arguments_check.py +129 -0
- hare/contrib/mypy/hare_mypy_plugin.py +166 -0
- hare/contrib/mypy/instance_attribute_types.py +137 -0
- hare/contrib/mypy/model_registry.py +127 -0
- hare/contrib/mypy/mypy_types.py +383 -0
- hare/contrib/mypy/queryset_extension_methods.py +109 -0
- hare/contrib/mypy/values_row_types.py +146 -0
- hare/contrib/mypy/write_arguments_check.py +159 -0
- hare/contrib/notify/__init__.py +5 -0
- hare/contrib/notify/constants.py +14 -0
- hare/contrib/notify/notification_listener.py +317 -0
- hare/contrib/opentelemetry/__init__.py +16 -0
- hare/contrib/opentelemetry/constants.py +31 -0
- hare/contrib/opentelemetry/open_telemetry_instrumentor.py +60 -0
- hare/contrib/opentelemetry/pool_metric_instruments.py +210 -0
- hare/contrib/opentelemetry/query_spans.py +69 -0
- hare/contrib/outbox/__init__.py +65 -0
- hare/contrib/outbox/broker_arguments.py +40 -0
- hare/contrib/outbox/brokers/__init__.py +1 -0
- hare/contrib/outbox/brokers/rabbitmq_connection.py +55 -0
- hare/contrib/outbox/brokers/redis_connection.py +42 -0
- hare/contrib/outbox/capture/__init__.py +6 -0
- hare/contrib/outbox/capture/change_capture.py +366 -0
- hare/contrib/outbox/capture/change_extension.py +22 -0
- hare/contrib/outbox/capture/constants.py +19 -0
- hare/contrib/outbox/constants.py +31 -0
- hare/contrib/outbox/deliveries/__init__.py +22 -0
- hare/contrib/outbox/deliveries/callable_delivery.py +44 -0
- hare/contrib/outbox/deliveries/constants.py +19 -0
- hare/contrib/outbox/deliveries/kafka_delivery.py +124 -0
- hare/contrib/outbox/deliveries/outbox_delivery.py +106 -0
- hare/contrib/outbox/deliveries/rabbitmq_delivery.py +63 -0
- hare/contrib/outbox/deliveries/redis_streams_delivery.py +110 -0
- hare/contrib/outbox/deliveries/topic_router.py +103 -0
- hare/contrib/outbox/deliveries/webhook_delivery.py +106 -0
- hare/contrib/outbox/exceptions.py +7 -0
- hare/contrib/outbox/outbox_event.py +362 -0
- hare/contrib/outbox/outbox_json_encoding.py +87 -0
- hare/contrib/outbox/relay/__init__.py +7 -0
- hare/contrib/outbox/relay/constants.py +41 -0
- hare/contrib/outbox/relay/declarations.py +76 -0
- hare/contrib/outbox/relay/outbox_backlog.py +18 -0
- hare/contrib/outbox/relay/outbox_relay.py +646 -0
- hare/contrib/outbox/wakeups/__init__.py +20 -0
- hare/contrib/outbox/wakeups/constants.py +20 -0
- hare/contrib/outbox/wakeups/in_process_wakeup.py +17 -0
- hare/contrib/outbox/wakeups/kafka_wakeup.py +123 -0
- hare/contrib/outbox/wakeups/listen_notify_wakeup.py +75 -0
- hare/contrib/outbox/wakeups/outbox_wakeup.py +202 -0
- hare/contrib/outbox/wakeups/rabbitmq_wakeup.py +64 -0
- hare/contrib/outbox/wakeups/redis_wakeup.py +53 -0
- hare/contrib/pydantic/__init__.py +12 -0
- hare/contrib/pydantic/constants.py +41 -0
- hare/contrib/pydantic/creation/__init__.py +1 -0
- hare/contrib/pydantic/creation/computed_field_schemas.py +77 -0
- hare/contrib/pydantic/creation/data_field_schemas.py +230 -0
- hare/contrib/pydantic/creation/field_descriptions.py +17 -0
- hare/contrib/pydantic/creation/field_map.py +138 -0
- hare/contrib/pydantic/creation/generic_foreign_key_schemas.py +136 -0
- hare/contrib/pydantic/creation/generic_foreign_key_tag_reader.py +35 -0
- hare/contrib/pydantic/creation/model_annotations.py +44 -0
- hare/contrib/pydantic/creation/pydantic_creators.py +163 -0
- hare/contrib/pydantic/creation/pydantic_meta_reading.py +134 -0
- hare/contrib/pydantic/creation/pydantic_model_creator.py +434 -0
- hare/contrib/pydantic/creation/relation_field_schemas.py +269 -0
- hare/contrib/pydantic/descriptions/__init__.py +5 -0
- hare/contrib/pydantic/descriptions/computed_field_description.py +12 -0
- hare/contrib/pydantic/descriptions/model_description.py +69 -0
- hare/contrib/pydantic/descriptions/pydantic_meta_data.py +144 -0
- hare/contrib/pydantic/enums.py +12 -0
- hare/contrib/pydantic/models/__init__.py +9 -0
- hare/contrib/pydantic/models/pydantic_list_model.py +34 -0
- hare/contrib/pydantic/models/pydantic_model.py +292 -0
- hare/contrib/pytest/__init__.py +17 -0
- hare/contrib/pytest/constants.py +26 -0
- hare/contrib/pytest/hare_fixtures.py +112 -0
- hare/contrib/pytest/missing_pytest_asyncio_fixtures.py +34 -0
- hare/contrib/pytest/plugin.py +49 -0
- hare/contrib/repeated_queries/__init__.py +19 -0
- hare/contrib/repeated_queries/constants.py +10 -0
- hare/contrib/repeated_queries/repeated_query_collection.py +116 -0
- hare/contrib/repeated_queries/repeated_query_detector.py +227 -0
- hare/contrib/repeated_queries/repeated_query_entry.py +20 -0
- hare/contrib/repeated_queries/repeated_query_report.py +31 -0
- hare/contrib/repeated_queries/shape_stats.py +18 -0
- hare/contrib/request_query/__init__.py +71 -0
- hare/contrib/request_query/bounds/__init__.py +6 -0
- hare/contrib/request_query/bounds/constants.py +4 -0
- hare/contrib/request_query/bounds/lookup_pair_bounds.py +40 -0
- hare/contrib/request_query/bounds/parameter_bounds.py +41 -0
- hare/contrib/request_query/bounds/range_bounds.py +30 -0
- hare/contrib/request_query/constants.py +45 -0
- hare/contrib/request_query/declaration/__init__.py +6 -0
- hare/contrib/request_query/declaration/constants.py +19 -0
- hare/contrib/request_query/declaration/declaration_builder.py +515 -0
- hare/contrib/request_query/declaration/filter_declaration.py +25 -0
- hare/contrib/request_query/declaration/filter_parameter_builder.py +201 -0
- hare/contrib/request_query/declaration/parameter_filter.py +17 -0
- hare/contrib/request_query/declaration/request_query_declaration.py +138 -0
- hare/contrib/request_query/declaration/request_query_parameters.py +54 -0
- hare/contrib/request_query/declaration/request_query_registry.py +90 -0
- hare/contrib/request_query/descriptions/__init__.py +11 -0
- hare/contrib/request_query/descriptions/constants.py +11 -0
- hare/contrib/request_query/descriptions/parameter_choice.py +17 -0
- hare/contrib/request_query/descriptions/parameter_describer.py +240 -0
- hare/contrib/request_query/descriptions/parameter_description.py +66 -0
- hare/contrib/request_query/descriptions/relation_description.py +30 -0
- hare/contrib/request_query/enums.py +69 -0
- hare/contrib/request_query/exceptions.py +52 -0
- hare/contrib/request_query/options/__init__.py +33 -0
- hare/contrib/request_query/options/constants.py +25 -0
- hare/contrib/request_query/options/deleted_config.py +90 -0
- hare/contrib/request_query/options/fields_config.py +55 -0
- hare/contrib/request_query/options/filter.py +34 -0
- hare/contrib/request_query/options/filter_field.py +81 -0
- hare/contrib/request_query/options/in_path.py +12 -0
- hare/contrib/request_query/options/include_config.py +56 -0
- hare/contrib/request_query/options/latest_versions.py +71 -0
- hare/contrib/request_query/options/no_filter.py +11 -0
- hare/contrib/request_query/options/ordering_config.py +81 -0
- hare/contrib/request_query/options/parameter_field.py +27 -0
- hare/contrib/request_query/options/request_option.py +152 -0
- hare/contrib/request_query/options/search_config.py +83 -0
- hare/contrib/request_query/paginations/__init__.py +1 -0
- hare/contrib/request_query/paginations/base_offset_pagination.py +78 -0
- hare/contrib/request_query/paginations/constants.py +17 -0
- hare/contrib/request_query/paginations/cursor.py +83 -0
- hare/contrib/request_query/paginations/cursor_pagination.py +184 -0
- hare/contrib/request_query/paginations/offset_pagination.py +31 -0
- hare/contrib/request_query/paginations/pagination.py +120 -0
- hare/contrib/request_query/paginations/scroll_pagination.py +31 -0
- hare/contrib/request_query/request_query.py +1259 -0
- hare/contrib/request_query/results/__init__.py +11 -0
- hare/contrib/request_query/results/cursor_page.py +25 -0
- hare/contrib/request_query/results/page.py +25 -0
- hare/contrib/request_query/results/scroll_page.py +23 -0
- hare/contrib/request_query/row_changes.py +80 -0
- hare/contrib/request_query/types/__init__.py +15 -0
- hare/contrib/request_query/types/comma_separated.py +46 -0
- hare/contrib/request_query/types/constants.py +16 -0
- hare/contrib/request_query/types/generic_target.py +87 -0
- hare/contrib/request_query/types/key_columns.py +60 -0
- hare/contrib/request_query/types/text_parameter.py +18 -0
- hare/contrib/request_query/value_annotation.py +216 -0
- hare/contrib/request_query/value_counter.py +115 -0
- hare/contrib/request_query/value_target.py +50 -0
- hare/contrib/taskiq/__init__.py +15 -0
- hare/contrib/taskiq/constants.py +23 -0
- hare/contrib/taskiq/hare_taskiq.py +76 -0
- hare/contrib/taskiq/hare_taskiq_middleware.py +195 -0
- hare/contrib/taskiq/running_task.py +29 -0
- hare/contrib/taskiq/task_tenant_labels.py +102 -0
- hare/contrib/taskiq/taskiq_delivery.py +117 -0
- hare/contrib/test/__init__.py +39 -0
- hare/contrib/test/conditions/__init__.py +10 -0
- hare/contrib/test/conditions/condition.py +11 -0
- hare/contrib/test/conditions/in_condition.py +21 -0
- hare/contrib/test/conditions/not_eq.py +18 -0
- hare/contrib/test/conditions/not_in.py +21 -0
- hare/contrib/test/constants.py +18 -0
- hare/contrib/test/databases/__init__.py +1 -0
- hare/contrib/test/databases/kept_test_schema.py +51 -0
- hare/contrib/test/databases/model_truncation.py +128 -0
- hare/contrib/test/databases/reusable_test_databases.py +244 -0
- hare/contrib/test/databases/rollback_isolation.py +149 -0
- hare/contrib/test/databases/temporary_databases.py +118 -0
- hare/contrib/test/exceptions.py +5 -0
- hare/contrib/test/features/__init__.py +1 -0
- hare/contrib/test/features/feature_conditions.py +65 -0
- hare/contrib/test/features/feature_requirements.py +84 -0
- hare/contrib/test/isolated_contexts.py +144 -0
- hare/contrib/test/queries/__init__.py +1 -0
- hare/contrib/test/queries/query_counter.py +35 -0
- hare/contrib/test/queries/query_counting.py +59 -0
- hare/contrib/versioning/__init__.py +7 -0
- hare/contrib/versioning/constants.py +5 -0
- hare/contrib/versioning/versioned_model.py +139 -0
- hare/core/__init__.py +4 -0
- hare/core/apps/__init__.py +8 -0
- hare/core/apps/apps.py +693 -0
- hare/core/apps/cross_connection_checks.py +76 -0
- hare/core/apps/model_connection_checks.py +199 -0
- hare/core/apps/model_discovery.py +142 -0
- hare/core/apps/relation_linking.py +773 -0
- hare/core/apps/swappable_models.py +118 -0
- hare/core/apps/table_names.py +39 -0
- hare/core/caching/__init__.py +1 -0
- hare/core/caching/cache.py +426 -0
- hare/core/caching/caches.py +58 -0
- hare/core/caching/constants.py +13 -0
- hare/core/caching/declarations.py +8 -0
- hare/core/caching/forgettable_cache.py +16 -0
- hare/core/caching/model_cache.py +138 -0
- hare/core/config/__init__.py +25 -0
- hare/core/config/app_config.py +64 -0
- hare/core/config/cli_config.py +38 -0
- hare/core/config/config_secrets.py +101 -0
- hare/core/config/config_section.py +37 -0
- hare/core/config/connection_config.py +69 -0
- hare/core/config/constants.py +17 -0
- hare/core/config/db_url_config.py +24 -0
- hare/core/config/hare_config.py +407 -0
- hare/core/config/migration_safety_config.py +54 -0
- hare/core/config/migrations_config.py +72 -0
- hare/core/connections/__init__.py +1 -0
- hare/core/connections/connection_handler.py +457 -0
- hare/core/connections/connection_token.py +36 -0
- hare/core/connections/connections.py +133 -0
- hare/core/constants.py +40 -0
- hare/core/hare.py +205 -0
- hare/core/hare_context.py +854 -0
- hare/core/hare_meta.py +18 -0
- hare/core/log.py +6 -0
- hare/core/registries.py +22 -0
- hare/core/routing/__init__.py +5 -0
- hare/core/routing/connection_router.py +109 -0
- hare/core/routing/primary_reads.py +42 -0
- hare/core/routing/routing.py +28 -0
- hare/core/routing/written_connections.py +63 -0
- hare/ddl/__init__.py +57 -0
- hare/ddl/conditions/__init__.py +1 -0
- hare/ddl/conditions/constraint_condition.py +154 -0
- hare/ddl/conditions/exclusive_arc_condition.py +80 -0
- hare/ddl/conditions/tenant_condition.py +48 -0
- hare/ddl/conditions/trigger_condition.py +44 -0
- hare/ddl/constants.py +68 -0
- hare/ddl/constraints/__init__.py +7 -0
- hare/ddl/constraints/check_constraint.py +38 -0
- hare/ddl/constraints/exclusion_constraint.py +116 -0
- hare/ddl/constraints/foreign_key_constraint.py +39 -0
- hare/ddl/constraints/unique_constraint.py +150 -0
- hare/ddl/ddl_term_sql.py +45 -0
- hare/ddl/declared_names.py +47 -0
- hare/ddl/enums.py +117 -0
- hare/ddl/expressions/__init__.py +0 -0
- hare/ddl/expressions/declared_expressions.py +102 -0
- hare/ddl/expressions/expression_field_renaming.py +150 -0
- hare/ddl/generated_names.py +87 -0
- hare/ddl/indexes/__init__.py +11 -0
- hare/ddl/indexes/index.py +531 -0
- hare/ddl/indexes/ordered_index_key.py +27 -0
- hare/ddl/indexes/partial_index.py +75 -0
- hare/ddl/raw_sql_term.py +44 -0
- hare/ddl/schema_objects/__init__.py +12 -0
- hare/ddl/schema_objects/database_function.py +91 -0
- hare/ddl/schema_objects/database_sequence.py +87 -0
- hare/ddl/schema_objects/dictionary.py +69 -0
- hare/ddl/schema_objects/enum_type.py +24 -0
- hare/ddl/schema_objects/materialized_view.py +52 -0
- hare/ddl/schema_objects/named_schema_object.py +24 -0
- hare/ddl/schema_objects/trigger.py +151 -0
- hare/ddl/schema_objects/view.py +132 -0
- hare/ddl/security/__init__.py +8 -0
- hare/ddl/security/grant.py +106 -0
- hare/ddl/security/policy.py +92 -0
- hare/ddl/table_options.py +364 -0
- hare/dialects/__init__.py +0 -0
- hare/dialects/base/__init__.py +0 -0
- hare/dialects/base/clauses/__init__.py +1 -0
- hare/dialects/base/clauses/enums.py +37 -0
- hare/dialects/base/clauses/limit_returning_conflict_query_clauses.py +194 -0
- hare/dialects/base/clauses/merge_when_sql.py +24 -0
- hare/dialects/base/clauses/query_clauses.py +636 -0
- hare/dialects/base/client/__init__.py +16 -0
- hare/dialects/base/client/connect_failure_reports.py +49 -0
- hare/dialects/base/client/connection_ping.py +48 -0
- hare/dialects/base/client/connection_wrapper.py +126 -0
- hare/dialects/base/client/constants.py +41 -0
- hare/dialects/base/client/database_client.py +1187 -0
- hare/dialects/base/client/declarations.py +37 -0
- hare/dialects/base/client/driver_statement_log_filter.py +33 -0
- hare/dialects/base/client/password_provider.py +144 -0
- hare/dialects/base/client/pool/__init__.py +1 -0
- hare/dialects/base/client/pool/pool_connection_wrapper.py +37 -0
- hare/dialects/base/client/pool/pool_statistics.py +84 -0
- hare/dialects/base/client/pool/pool_timeouts.py +48 -0
- hare/dialects/base/client/transaction_client.py +621 -0
- hare/dialects/base/client/transaction_lifecycle/__init__.py +1 -0
- hare/dialects/base/client/transaction_lifecycle/pending_statements.py +74 -0
- hare/dialects/base/client/transaction_lifecycle/transaction_callbacks.py +128 -0
- hare/dialects/base/client/transaction_lifecycle/transaction_ending.py +360 -0
- hare/dialects/base/connection/__init__.py +1 -0
- hare/dialects/base/connection/connection_option.py +142 -0
- hare/dialects/base/connection/connection_options.py +69 -0
- hare/dialects/base/connection/constants.py +27 -0
- hare/dialects/base/connection/db_url_config_generator.py +194 -0
- hare/dialects/base/connection/driver.py +136 -0
- hare/dialects/base/constants.py +72 -0
- hare/dialects/base/dialect.py +360 -0
- hare/dialects/base/features.py +369 -0
- hare/dialects/base/literals/__init__.py +1 -0
- hare/dialects/base/literals/constants.py +12 -0
- hare/dialects/base/literals/sql_literals.py +254 -0
- hare/dialects/base/lookups/__init__.py +1 -0
- hare/dialects/base/lookups/filter_operators.py +171 -0
- hare/dialects/base/migration_safety/__init__.py +12 -0
- hare/dialects/base/migration_safety/add_field_backfill_rule.py +37 -0
- hare/dialects/base/migration_safety/alter_field_rewrite_rule.py +39 -0
- hare/dialects/base/migration_safety/constants.py +4 -0
- hare/dialects/base/migration_safety/delete_model_rule.py +33 -0
- hare/dialects/base/migration_safety/migration_safety_rule.py +45 -0
- hare/dialects/base/migration_safety/migration_safety_rules.py +72 -0
- hare/dialects/base/migration_safety/remove_field_rule.py +31 -0
- hare/dialects/base/migration_safety/rename_field_rule.py +41 -0
- hare/dialects/base/migration_safety/rename_model_rule.py +42 -0
- hare/dialects/base/migration_safety/run_sql_rule.py +27 -0
- hare/dialects/base/migration_safety/schema_change_with_run_python_rule.py +49 -0
- hare/dialects/base/parameters/__init__.py +1 -0
- hare/dialects/base/parameters/large_in_list.py +147 -0
- hare/dialects/base/parameters/sql_parameters.py +185 -0
- hare/dialects/base/renderers/__init__.py +7 -0
- hare/dialects/base/renderers/checked_term_renderers.py +61 -0
- hare/dialects/base/renderers/json_renderers.py +60 -0
- hare/dialects/base/renderers/term_renderers.py +508 -0
- hare/dialects/base/results/__init__.py +9 -0
- hare/dialects/base/results/described_result.py +22 -0
- hare/dialects/base/results/statement_result.py +53 -0
- hare/dialects/base/schema/__init__.py +0 -0
- hare/dialects/base/schema/base_schema_editor.py +1139 -0
- hare/dialects/base/schema/columns/__init__.py +1 -0
- hare/dialects/base/schema/columns/column_backfill.py +347 -0
- hare/dialects/base/schema/columns/column_conversion_check.py +51 -0
- hare/dialects/base/schema/columns/column_definitions.py +473 -0
- hare/dialects/base/schema/columns/column_narrowing_check.py +178 -0
- hare/dialects/base/schema/columns/column_renames.py +77 -0
- hare/dialects/base/schema/columns/column_type_changes.py +140 -0
- hare/dialects/base/schema/constants.py +30 -0
- hare/dialects/base/schema/constraints/__init__.py +1 -0
- hare/dialects/base/schema/constraints/constraint_names.py +45 -0
- hare/dialects/base/schema/constraints/constraint_statements.py +262 -0
- hare/dialects/base/schema/data/__init__.py +9 -0
- hare/dialects/base/schema/data/model_sql_data.py +41 -0
- hare/dialects/base/schema/data/referencing_key_columns.py +24 -0
- hare/dialects/base/schema/indexes/__init__.py +1 -0
- hare/dialects/base/schema/indexes/generated_index_names.py +180 -0
- hare/dialects/base/schema/indexes/index_statements.py +397 -0
- hare/dialects/base/schema/relations/__init__.py +1 -0
- hare/dialects/base/schema/relations/foreign_key_rebuild.py +480 -0
- hare/dialects/base/schema/relations/many_to_many_through_tables.py +285 -0
- hare/dialects/base/schema/runtime_statements/__init__.py +1 -0
- hare/dialects/base/schema/runtime_statements/table_clearing.py +54 -0
- hare/dialects/base/schema/runtime_statements/table_locks.py +34 -0
- hare/dialects/base/schema/runtime_statements/tenant_conditions.py +71 -0
- hare/dialects/base/schema/schema_editor_part.py +34 -0
- hare/dialects/base/schema/schema_objects/__init__.py +1 -0
- hare/dialects/base/schema/schema_objects/database_functions.py +74 -0
- hare/dialects/base/schema/schema_objects/dictionaries.py +75 -0
- hare/dialects/base/schema/schema_objects/enum_types.py +88 -0
- hare/dialects/base/schema/schema_objects/extensions.py +69 -0
- hare/dialects/base/schema/schema_objects/grants.py +49 -0
- hare/dialects/base/schema/schema_objects/materialized_views.py +111 -0
- hare/dialects/base/schema/schema_objects/row_level_security_policies.py +82 -0
- hare/dialects/base/schema/schema_objects/schemas.py +65 -0
- hare/dialects/base/schema/schema_objects/sequences.py +95 -0
- hare/dialects/base/schema/schema_objects/views.py +81 -0
- hare/dialects/base/schema/shadow/__init__.py +0 -0
- hare/dialects/base/schema/shadow/shadow_database.py +77 -0
- hare/dialects/base/schema/tables/__init__.py +1 -0
- hare/dialects/base/schema/tables/table_comments.py +92 -0
- hare/dialects/base/schema/tables/table_creation.py +742 -0
- hare/dialects/base/schema/tables/table_partitions.py +78 -0
- hare/dialects/base/schema/tables/table_rebuild.py +268 -0
- hare/dialects/base/schema/triggers/__init__.py +1 -0
- hare/dialects/base/schema/triggers/trigger_statements.py +85 -0
- hare/dialects/base/search/__init__.py +1 -0
- hare/dialects/base/search/text_search.py +135 -0
- hare/dialects/base/sql_dialect.py +23 -0
- hare/dialects/base/transactions/__init__.py +1 -0
- hare/dialects/base/transactions/constants.py +5 -0
- hare/dialects/base/transactions/contexts/__init__.py +1 -0
- hare/dialects/base/transactions/contexts/joined_transaction_context.py +36 -0
- hare/dialects/base/transactions/contexts/nested_transaction_context.py +149 -0
- hare/dialects/base/transactions/contexts/non_transactional_context.py +32 -0
- hare/dialects/base/transactions/contexts/top_level_transaction_context.py +79 -0
- hare/dialects/base/transactions/contexts/transaction_context.py +148 -0
- hare/dialects/base/transactions/savepoints/__init__.py +1 -0
- hare/dialects/base/transactions/savepoints/nested_savepoint_lock.py +152 -0
- hare/dialects/base/transactions/savepoints/savepoint_span.py +51 -0
- hare/dialects/base/transactions/transaction_callback.py +32 -0
- hare/dialects/base/transactions/transaction_statements.py +128 -0
- hare/dialects/base/transactions/two_phase_commit.py +134 -0
- hare/dialects/base/types/__init__.py +9 -0
- hare/dialects/base/types/type_mapping.py +63 -0
- hare/dialects/base/types/type_registry.py +395 -0
- hare/dialects/clickhouse/__init__.py +1 -0
- hare/dialects/clickhouse/clauses/__init__.py +1 -0
- hare/dialects/clickhouse/clauses/clickhouse_query_clauses.py +475 -0
- hare/dialects/clickhouse/clauses/constants.py +42 -0
- hare/dialects/clickhouse/clickhouse_dialect.py +260 -0
- hare/dialects/clickhouse/clickhouse_introspector.py +414 -0
- hare/dialects/clickhouse/clickhouse_table_options.py +727 -0
- hare/dialects/clickhouse/client/__init__.py +1 -0
- hare/dialects/clickhouse/client/clickhouse_client.py +913 -0
- hare/dialects/clickhouse/client/clickhouse_connection.py +30 -0
- hare/dialects/clickhouse/client/clickhouse_error_codes.py +26 -0
- hare/dialects/clickhouse/client/clickhouse_external_sets.py +109 -0
- hare/dialects/clickhouse/client/clickhouse_query_templates.py +79 -0
- hare/dialects/clickhouse/client/clickhouse_statement_result.py +15 -0
- hare/dialects/clickhouse/client/clickhouse_streamed_row.py +52 -0
- hare/dialects/clickhouse/client/clickhouse_transaction_client.py +188 -0
- hare/dialects/clickhouse/client/constants.py +211 -0
- hare/dialects/clickhouse/client/declarations.py +47 -0
- hare/dialects/clickhouse/cluster/__init__.py +0 -0
- hare/dialects/clickhouse/cluster/clickhouse_cluster.py +162 -0
- hare/dialects/clickhouse/cluster/clickhouse_cluster_statements.py +154 -0
- hare/dialects/clickhouse/cluster/constants.py +82 -0
- hare/dialects/clickhouse/connection/__init__.py +1 -0
- hare/dialects/clickhouse/connection/clickhouse_driver.py +40 -0
- hare/dialects/clickhouse/constants.py +226 -0
- hare/dialects/clickhouse/drivers/__init__.py +1 -0
- hare/dialects/clickhouse/drivers/clickhouse_connect/__init__.py +1 -0
- hare/dialects/clickhouse/drivers/clickhouse_connect/clickhouse_connect_driver.py +43 -0
- hare/dialects/clickhouse/drivers/clickhouse_connect/client/__init__.py +1 -0
- hare/dialects/clickhouse/drivers/clickhouse_connect/client/clickhouse_connect_client.py +390 -0
- hare/dialects/clickhouse/drivers/clickhouse_connect/client/clickhouse_connect_dynamic_type.py +76 -0
- hare/dialects/clickhouse/drivers/clickhouse_connect/client/clickhouse_connect_totals_query.py +70 -0
- hare/dialects/clickhouse/drivers/clickhouse_connect/client/clickhouse_connect_transaction_client.py +56 -0
- hare/dialects/clickhouse/drivers/clickhouse_connect/client/clickhouse_connect_whole_response_query.py +127 -0
- hare/dialects/clickhouse/drivers/clickhouse_connect/client/clickhouse_json_compact_values.py +96 -0
- hare/dialects/clickhouse/drivers/clickhouse_connect/constants.py +60 -0
- hare/dialects/clickhouse/drivers/clickhouse_driver/__init__.py +1 -0
- hare/dialects/clickhouse/drivers/clickhouse_driver/clickhouse_driver_driver.py +48 -0
- hare/dialects/clickhouse/drivers/clickhouse_driver/client/__init__.py +1 -0
- hare/dialects/clickhouse/drivers/clickhouse_driver/client/clickhouse_driver_client.py +361 -0
- hare/dialects/clickhouse/drivers/clickhouse_driver/client/clickhouse_driver_client_info.py +70 -0
- hare/dialects/clickhouse/drivers/clickhouse_driver/client/clickhouse_driver_column_types.py +104 -0
- hare/dialects/clickhouse/drivers/clickhouse_driver/client/clickhouse_driver_connections.py +189 -0
- hare/dialects/clickhouse/drivers/clickhouse_driver/client/clickhouse_driver_decompressors.py +48 -0
- hare/dialects/clickhouse/drivers/clickhouse_driver/client/clickhouse_driver_dynamic_column.py +51 -0
- hare/dialects/clickhouse/drivers/clickhouse_driver/client/clickhouse_driver_library_client.py +239 -0
- hare/dialects/clickhouse/drivers/clickhouse_driver/client/clickhouse_driver_library_connection.py +16 -0
- hare/dialects/clickhouse/drivers/clickhouse_driver/client/clickhouse_driver_map_columns.py +49 -0
- hare/dialects/clickhouse/drivers/clickhouse_driver/client/clickhouse_driver_moment_columns.py +85 -0
- hare/dialects/clickhouse/drivers/clickhouse_driver/client/clickhouse_driver_query_result.py +24 -0
- hare/dialects/clickhouse/drivers/clickhouse_driver/client/clickhouse_driver_row_stream.py +127 -0
- hare/dialects/clickhouse/drivers/clickhouse_driver/client/clickhouse_driver_service_block_stream.py +95 -0
- hare/dialects/clickhouse/drivers/clickhouse_driver/client/clickhouse_driver_settings.py +62 -0
- hare/dialects/clickhouse/drivers/clickhouse_driver/client/clickhouse_driver_transaction_client.py +23 -0
- hare/dialects/clickhouse/drivers/clickhouse_driver/client/clickhouse_driver_tuple_columns.py +38 -0
- hare/dialects/clickhouse/drivers/clickhouse_driver/client/clickhouse_driver_variant_column.py +76 -0
- hare/dialects/clickhouse/drivers/clickhouse_driver/constants.py +133 -0
- hare/dialects/clickhouse/drivers/clickhouse_shared_variant_values.py +878 -0
- hare/dialects/clickhouse/drivers/constants.py +143 -0
- hare/dialects/clickhouse/enums.py +38 -0
- hare/dialects/clickhouse/fields/__init__.py +43 -0
- hare/dialects/clickhouse/fields/clickhouse_date_field.py +32 -0
- hare/dialects/clickhouse/fields/clickhouse_datetime_field.py +162 -0
- hare/dialects/clickhouse/fields/clickhouse_integer_field.py +20 -0
- hare/dialects/clickhouse/fields/constants.py +31 -0
- hare/dialects/clickhouse/fields/declarations.py +81 -0
- hare/dialects/clickhouse/fields/dynamic_field.py +122 -0
- hare/dialects/clickhouse/fields/fixed_string_field.py +81 -0
- hare/dialects/clickhouse/fields/float32_field.py +39 -0
- hare/dialects/clickhouse/fields/low_cardinality_field.py +72 -0
- hare/dialects/clickhouse/fields/variant_field.py +174 -0
- hare/dialects/clickhouse/functions/__init__.py +39 -0
- hare/dialects/clickhouse/functions/aggregates/__init__.py +37 -0
- hare/dialects/clickhouse/functions/aggregates/arg_extremum.py +23 -0
- hare/dialects/clickhouse/functions/aggregates/declarations.py +120 -0
- hare/dialects/clickhouse/functions/aggregates/group_array.py +48 -0
- hare/dialects/clickhouse/functions/aggregates/median.py +18 -0
- hare/dialects/clickhouse/functions/aggregates/parametric_aggregate.py +48 -0
- hare/dialects/clickhouse/functions/aggregates/parametric_aggregate_function.py +45 -0
- hare/dialects/clickhouse/functions/aggregates/parametric_analytic_function.py +27 -0
- hare/dialects/clickhouse/functions/aggregates/quantile.py +74 -0
- hare/dialects/clickhouse/functions/aggregates/quantiles.py +58 -0
- hare/dialects/clickhouse/functions/aggregates/top_k.py +44 -0
- hare/dialects/clickhouse/functions/dict_get.py +199 -0
- hare/dialects/clickhouse/indexes/__init__.py +19 -0
- hare/dialects/clickhouse/indexes/bloom_filter_index.py +49 -0
- hare/dialects/clickhouse/indexes/clickhouse_index.py +145 -0
- hare/dialects/clickhouse/indexes/constants.py +14 -0
- hare/dialects/clickhouse/indexes/min_max_index.py +22 -0
- hare/dialects/clickhouse/indexes/ngram_bloom_filter_index.py +43 -0
- hare/dialects/clickhouse/indexes/set_index.py +35 -0
- hare/dialects/clickhouse/indexes/token_bloom_filter_index.py +60 -0
- hare/dialects/clickhouse/introspection/__init__.py +0 -0
- hare/dialects/clickhouse/introspection/clickhouse_check_constraints.py +40 -0
- hare/dialects/clickhouse/introspection/clickhouse_observed_table_options.py +280 -0
- hare/dialects/clickhouse/introspection/clickhouse_sql_parts.py +302 -0
- hare/dialects/clickhouse/introspection/clickhouse_type_parser.py +276 -0
- hare/dialects/clickhouse/introspection/constants.py +69 -0
- hare/dialects/clickhouse/keeper/__init__.py +0 -0
- hare/dialects/clickhouse/keeper/clickhouse_migration_lock.py +114 -0
- hare/dialects/clickhouse/keeper/constants.py +38 -0
- hare/dialects/clickhouse/keeper/keeper_codec.py +152 -0
- hare/dialects/clickhouse/keeper/keeper_session.py +213 -0
- hare/dialects/clickhouse/literals/__init__.py +1 -0
- hare/dialects/clickhouse/literals/clickhouse_literals.py +362 -0
- hare/dialects/clickhouse/lookups/__init__.py +0 -0
- hare/dialects/clickhouse/lookups/clickhouse_array_elements_key.py +32 -0
- hare/dialects/clickhouse/lookups/clickhouse_filter_operators.py +49 -0
- hare/dialects/clickhouse/lookups/clickhouse_global_lookups.py +129 -0
- hare/dialects/clickhouse/lookups/clickhouse_json_equality.py +78 -0
- hare/dialects/clickhouse/lookups/clickhouse_json_key_existence.py +38 -0
- hare/dialects/clickhouse/lookups/clickhouse_json_lookups.py +57 -0
- hare/dialects/clickhouse/lookups/clickhouse_json_path_lookups.py +102 -0
- hare/dialects/clickhouse/lookups/clickhouse_json_value_text.py +24 -0
- hare/dialects/clickhouse/lookups/clickhouse_typed_value_lookups.py +213 -0
- hare/dialects/clickhouse/lookups/constants.py +67 -0
- hare/dialects/clickhouse/lookups/declarations.py +14 -0
- hare/dialects/clickhouse/lookups/global_contains_criterion.py +15 -0
- hare/dialects/clickhouse/lookups/in_list/__init__.py +0 -0
- hare/dialects/clickhouse/lookups/in_list/clickhouse_large_in_list.py +95 -0
- hare/dialects/clickhouse/lookups/in_list/clickhouse_value_set_values.py +45 -0
- hare/dialects/clickhouse/migration_safety/__init__.py +9 -0
- hare/dialects/clickhouse/migration_safety/clickhouse_migration_safety_rules.py +34 -0
- hare/dialects/clickhouse/migration_safety/constants.py +10 -0
- hare/dialects/clickhouse/parameters/__init__.py +1 -0
- hare/dialects/clickhouse/parameters/clickhouse_parameters.py +42 -0
- hare/dialects/clickhouse/query/__init__.py +1 -0
- hare/dialects/clickhouse/query/clickhouse_dialect_variants.py +31 -0
- hare/dialects/clickhouse/query/clickhouse_queryset_methods.py +356 -0
- hare/dialects/clickhouse/query/clickhouse_sql_context.py +47 -0
- hare/dialects/clickhouse/query/clickhouse_totals.py +34 -0
- hare/dialects/clickhouse/query/constants.py +24 -0
- hare/dialects/clickhouse/query/declarations.py +21 -0
- hare/dialects/clickhouse/query/totals_result.py +21 -0
- hare/dialects/clickhouse/renderers/__init__.py +1 -0
- hare/dialects/clickhouse/renderers/clickhouse_aggregate_renderers.py +124 -0
- hare/dialects/clickhouse/renderers/clickhouse_assigned_enum_number.py +30 -0
- hare/dialects/clickhouse/renderers/clickhouse_cast_renderers.py +49 -0
- hare/dialects/clickhouse/renderers/clickhouse_checked_integer_result.py +34 -0
- hare/dialects/clickhouse/renderers/clickhouse_condition_renderers.py +27 -0
- hare/dialects/clickhouse/renderers/clickhouse_container_renderers.py +129 -0
- hare/dialects/clickhouse/renderers/clickhouse_json_renderers.py +105 -0
- hare/dialects/clickhouse/renderers/clickhouse_json_texts.py +34 -0
- hare/dialects/clickhouse/renderers/clickhouse_number_renderers.py +76 -0
- hare/dialects/clickhouse/renderers/clickhouse_renderers.py +339 -0
- hare/dialects/clickhouse/renderers/clickhouse_temporal_renderers.py +262 -0
- hare/dialects/clickhouse/renderers/clickhouse_text_renderers.py +117 -0
- hare/dialects/clickhouse/renderers/clickhouse_value_casts.py +115 -0
- hare/dialects/clickhouse/renderers/clickhouse_window_renderers.py +72 -0
- hare/dialects/clickhouse/renderers/constants.py +341 -0
- hare/dialects/clickhouse/schema/__init__.py +1 -0
- hare/dialects/clickhouse/schema/columns/__init__.py +1 -0
- hare/dialects/clickhouse/schema/columns/clickhouse_column_backfill.py +106 -0
- hare/dialects/clickhouse/schema/columns/clickhouse_column_conversion_check.py +173 -0
- hare/dialects/clickhouse/schema/columns/clickhouse_column_definitions.py +62 -0
- hare/dialects/clickhouse/schema/columns/clickhouse_column_narrowing_check.py +109 -0
- hare/dialects/clickhouse/schema/columns/clickhouse_column_renames.py +45 -0
- hare/dialects/clickhouse/schema/constants.py +201 -0
- hare/dialects/clickhouse/schema/declarations.py +95 -0
- hare/dialects/clickhouse/schema/indexes/__init__.py +0 -0
- hare/dialects/clickhouse/schema/indexes/clickhouse_index_statements.py +60 -0
- hare/dialects/clickhouse/schema/runtime_statements/__init__.py +1 -0
- hare/dialects/clickhouse/schema/runtime_statements/clickhouse_table_clearing.py +19 -0
- hare/dialects/clickhouse/schema/schema_objects/__init__.py +0 -0
- hare/dialects/clickhouse/schema/schema_objects/clickhouse_dictionaries.py +169 -0
- hare/dialects/clickhouse/schema/schema_objects/clickhouse_materialized_views.py +221 -0
- hare/dialects/clickhouse/schema/schema_objects/clickhouse_schemas.py +69 -0
- hare/dialects/clickhouse/schema/schema_objects/clickhouse_views.py +59 -0
- hare/dialects/clickhouse/schema/shadow/__init__.py +0 -0
- hare/dialects/clickhouse/schema/shadow/clickhouse_shadow_database.py +155 -0
- hare/dialects/clickhouse/schema/tables/__init__.py +1 -0
- hare/dialects/clickhouse/schema/tables/clickhouse_table_comments.py +43 -0
- hare/dialects/clickhouse/schema/tables/clickhouse_table_creation.py +50 -0
- hare/dialects/clickhouse/schema/tables/clickhouse_table_partitions.py +160 -0
- hare/dialects/clickhouse/schema/tables/clickhouse_table_rebuild.py +227 -0
- hare/dialects/clickhouse/schema_objects/__init__.py +5 -0
- hare/dialects/clickhouse/schema_objects/clickhouse_dictionary.py +118 -0
- hare/dialects/clickhouse/schema_objects/clickhouse_materialized_view.py +159 -0
- hare/dialects/clickhouse/schema_objects/clickhouse_projection.py +204 -0
- hare/dialects/clickhouse/server_versions.py +5 -0
- hare/dialects/clickhouse/spatial/__init__.py +0 -0
- hare/dialects/clickhouse/spatial/clickhouse_geometry_values.py +208 -0
- hare/dialects/clickhouse/spatial/clickhouse_spatial_renderers.py +265 -0
- hare/dialects/clickhouse/spatial/constants.py +66 -0
- hare/dialects/clickhouse/transactions/__init__.py +0 -0
- hare/dialects/clickhouse/transactions/clickhouse_transaction_statements.py +19 -0
- hare/dialects/clickhouse/types/__init__.py +1 -0
- hare/dialects/clickhouse/types/clickhouse_address_values.py +35 -0
- hare/dialects/clickhouse/types/clickhouse_binary_values.py +58 -0
- hare/dialects/clickhouse/types/clickhouse_container_values.py +267 -0
- hare/dialects/clickhouse/types/clickhouse_dynamic_values.py +307 -0
- hare/dialects/clickhouse/types/clickhouse_enum_types.py +232 -0
- hare/dialects/clickhouse/types/clickhouse_json_values.py +202 -0
- hare/dialects/clickhouse/types/clickhouse_low_cardinality_values.py +95 -0
- hare/dialects/clickhouse/types/clickhouse_nullable_types.py +27 -0
- hare/dialects/clickhouse/types/clickhouse_type_names.py +128 -0
- hare/dialects/clickhouse/types/clickhouse_types.py +258 -0
- hare/dialects/clickhouse/types/clickhouse_variant_values.py +128 -0
- hare/dialects/clickhouse/types/constants.py +139 -0
- hare/dialects/clickhouse/types/declarations.py +23 -0
- hare/dialects/constants.py +32 -0
- hare/dialects/dialect_registry.py +340 -0
- hare/dialects/enums.py +34 -0
- hare/dialects/postgresql/__init__.py +0 -0
- hare/dialects/postgresql/clauses/__init__.py +1 -0
- hare/dialects/postgresql/clauses/constants.py +44 -0
- hare/dialects/postgresql/clauses/postgresql_query_clauses.py +114 -0
- hare/dialects/postgresql/client/__init__.py +10 -0
- hare/dialects/postgresql/client/constants.py +328 -0
- hare/dialects/postgresql/client/postgresql_client.py +1224 -0
- hare/dialects/postgresql/client/postgresql_connect_errors.py +66 -0
- hare/dialects/postgresql/client/postgresql_transaction_client.py +80 -0
- hare/dialects/postgresql/client/reusable_test_schemas.py +197 -0
- hare/dialects/postgresql/client/transaction_pooler.py +137 -0
- hare/dialects/postgresql/connection/__init__.py +1 -0
- hare/dialects/postgresql/connection/constants.py +11 -0
- hare/dialects/postgresql/connection/postgresql_driver.py +99 -0
- hare/dialects/postgresql/constants.py +862 -0
- hare/dialects/postgresql/drivers/__init__.py +0 -0
- hare/dialects/postgresql/drivers/asyncpg/__init__.py +0 -0
- hare/dialects/postgresql/drivers/asyncpg/asyncpg_date_codec.py +81 -0
- hare/dialects/postgresql/drivers/asyncpg/asyncpg_driver.py +37 -0
- hare/dialects/postgresql/drivers/asyncpg/asyncpg_extension_type_codecs.py +78 -0
- hare/dialects/postgresql/drivers/asyncpg/asyncpg_hstore_codec.py +84 -0
- hare/dialects/postgresql/drivers/asyncpg/asyncpg_interval_codec.py +72 -0
- hare/dialects/postgresql/drivers/asyncpg/asyncpg_timestamp_codec.py +74 -0
- hare/dialects/postgresql/drivers/asyncpg/asyncpg_timestamptz_codec.py +88 -0
- hare/dialects/postgresql/drivers/asyncpg/asyncpg_tsvector_codec.py +264 -0
- hare/dialects/postgresql/drivers/asyncpg/client/__init__.py +9 -0
- hare/dialects/postgresql/drivers/asyncpg/client/asyncpg_client.py +738 -0
- hare/dialects/postgresql/drivers/asyncpg/client/asyncpg_transaction_client.py +197 -0
- hare/dialects/postgresql/drivers/asyncpg/constants.py +150 -0
- hare/dialects/postgresql/drivers/asyncpg/pre_epoch_local_zone.py +27 -0
- hare/dialects/postgresql/drivers/constants.py +22 -0
- hare/dialects/postgresql/drivers/rust_pg/__init__.py +0 -0
- hare/dialects/postgresql/drivers/rust_pg/client/__init__.py +9 -0
- hare/dialects/postgresql/drivers/rust_pg/client/rust_pg_client.py +461 -0
- hare/dialects/postgresql/drivers/rust_pg/client/rust_pg_transaction_client.py +306 -0
- hare/dialects/postgresql/drivers/rust_pg/client/rust_pg_transaction_connection_wrapper.py +53 -0
- hare/dialects/postgresql/drivers/rust_pg/constants.py +43 -0
- hare/dialects/postgresql/drivers/rust_pg/rust_pg_driver.py +66 -0
- hare/dialects/postgresql/enums.py +99 -0
- hare/dialects/postgresql/fields/__init__.py +68 -0
- hare/dialects/postgresql/fields/citext_field.py +42 -0
- hare/dialects/postgresql/fields/constants.py +115 -0
- hare/dialects/postgresql/fields/fixed_char_field.py +23 -0
- hare/dialects/postgresql/fields/hstore/__init__.py +5 -0
- hare/dialects/postgresql/fields/hstore/h_store_field.py +105 -0
- hare/dialects/postgresql/fields/hstore/h_store_text.py +86 -0
- hare/dialects/postgresql/fields/interval_field.py +31 -0
- hare/dialects/postgresql/fields/ltree_field.py +98 -0
- hare/dialects/postgresql/fields/multiranges/__init__.py +19 -0
- hare/dialects/postgresql/fields/multiranges/declarations.py +55 -0
- hare/dialects/postgresql/fields/multiranges/multi_range_field.py +326 -0
- hare/dialects/postgresql/fields/naive_datetime_field.py +74 -0
- hare/dialects/postgresql/fields/naive_time_field.py +64 -0
- hare/dialects/postgresql/fields/native_enum/__init__.py +5 -0
- hare/dialects/postgresql/fields/native_enum/native_enum_field.py +23 -0
- hare/dialects/postgresql/fields/native_enum/native_enum_field_instance.py +87 -0
- hare/dialects/postgresql/fields/network/__init__.py +7 -0
- hare/dialects/postgresql/fields/network/cidr_field.py +24 -0
- hare/dialects/postgresql/fields/network/inet_field.py +25 -0
- hare/dialects/postgresql/fields/network/mac_address_field.py +59 -0
- hare/dialects/postgresql/fields/network/network_field.py +80 -0
- hare/dialects/postgresql/fields/postgis_field.py +206 -0
- hare/dialects/postgresql/fields/ranges/__init__.py +19 -0
- hare/dialects/postgresql/fields/ranges/date_range_field.py +48 -0
- hare/dialects/postgresql/fields/ranges/date_time_range_field.py +153 -0
- hare/dialects/postgresql/fields/ranges/decimal_range_field.py +42 -0
- hare/dialects/postgresql/fields/ranges/declarations.py +15 -0
- hare/dialects/postgresql/fields/ranges/int_range_field.py +60 -0
- hare/dialects/postgresql/fields/ranges/range.py +26 -0
- hare/dialects/postgresql/fields/ranges/range_field.py +349 -0
- hare/dialects/postgresql/fields/ts_vector_field.py +143 -0
- hare/dialects/postgresql/functions/__init__.py +72 -0
- hare/dialects/postgresql/functions/aggregates/__init__.py +21 -0
- hare/dialects/postgresql/functions/aggregates/declarations.py +67 -0
- hare/dialects/postgresql/functions/aggregates/jsonb_agg.py +35 -0
- hare/dialects/postgresql/functions/aggregates/jsonb_agg_field.py +29 -0
- hare/dialects/postgresql/functions/aggregates/range_agg.py +22 -0
- hare/dialects/postgresql/functions/aggregates/string_agg.py +101 -0
- hare/dialects/postgresql/functions/aggregates/string_agg_function.py +13 -0
- hare/dialects/postgresql/functions/array/__init__.py +13 -0
- hare/dialects/postgresql/functions/array/any_value.py +13 -0
- hare/dialects/postgresql/functions/array/array_slice.py +28 -0
- hare/dialects/postgresql/functions/array/array_subquery.py +62 -0
- hare/dialects/postgresql/functions/array/array_subscript.py +66 -0
- hare/dialects/postgresql/functions/constants.py +8 -0
- hare/dialects/postgresql/functions/ltree/__init__.py +7 -0
- hare/dialects/postgresql/functions/ltree/subpath.py +54 -0
- hare/dialects/postgresql/functions/random_uuid.py +26 -0
- hare/dialects/postgresql/functions/spatial/__init__.py +9 -0
- hare/dialects/postgresql/functions/spatial/st_distance.py +63 -0
- hare/dialects/postgresql/functions/spatial/std_within.py +46 -0
- hare/dialects/postgresql/functions/statistics/__init__.py +31 -0
- hare/dialects/postgresql/functions/statistics/covar_pop.py +49 -0
- hare/dialects/postgresql/functions/statistics/declarations.py +84 -0
- hare/dialects/postgresql/functions/statistics/regr_count.py +21 -0
- hare/dialects/postgresql/functions/statistics/statistic_pair_aggregate.py +55 -0
- hare/dialects/postgresql/functions/transaction_now.py +27 -0
- hare/dialects/postgresql/functions/trigram/__init__.py +21 -0
- hare/dialects/postgresql/functions/trigram/declarations.py +53 -0
- hare/dialects/postgresql/functions/trigram/trigram_function.py +61 -0
- hare/dialects/postgresql/functions/trigram/trigram_word_similarity.py +19 -0
- hare/dialects/postgresql/indexes/__init__.py +25 -0
- hare/dialects/postgresql/indexes/constants.py +16 -0
- hare/dialects/postgresql/indexes/declarations.py +36 -0
- hare/dialects/postgresql/indexes/hnsw_index.py +63 -0
- hare/dialects/postgresql/indexes/ivfflat_index.py +37 -0
- hare/dialects/postgresql/indexes/postgresql_index.py +112 -0
- hare/dialects/postgresql/introspection/__init__.py +0 -0
- hare/dialects/postgresql/introspection/postgresql_array_literals.py +101 -0
- hare/dialects/postgresql/introspection/postgresql_definitions.py +193 -0
- hare/dialects/postgresql/introspection/postgresql_inspected_schema_objects.py +196 -0
- hare/dialects/postgresql/introspection/postgresql_object_parts.py +102 -0
- hare/dialects/postgresql/literals/__init__.py +1 -0
- hare/dialects/postgresql/literals/postgresql_literals.py +99 -0
- hare/dialects/postgresql/lookups/__init__.py +0 -0
- hare/dialects/postgresql/lookups/array/__init__.py +5 -0
- hare/dialects/postgresql/lookups/array/array_length.py +26 -0
- hare/dialects/postgresql/lookups/constants.py +44 -0
- hare/dialects/postgresql/lookups/hstore/__init__.py +11 -0
- hare/dialects/postgresql/lookups/hstore/h_store_value_term.py +18 -0
- hare/dialects/postgresql/lookups/hstore/postgresql_h_store_field_lookups.py +75 -0
- hare/dialects/postgresql/lookups/hstore/postgresql_h_store_lookups.py +38 -0
- hare/dialects/postgresql/lookups/in_list/__init__.py +11 -0
- hare/dialects/postgresql/lookups/in_list/array_parameter.py +104 -0
- hare/dialects/postgresql/lookups/in_list/postgresql_large_in_list.py +78 -0
- hare/dialects/postgresql/lookups/in_list/unnest_row_values.py +32 -0
- hare/dialects/postgresql/lookups/json/__init__.py +9 -0
- hare/dialects/postgresql/lookups/json/postgresql_json_filter_guards.py +111 -0
- hare/dialects/postgresql/lookups/json/postgresql_json_lookups.py +59 -0
- hare/dialects/postgresql/lookups/ltree/__init__.py +9 -0
- hare/dialects/postgresql/lookups/ltree/postgresql_ltree_field_lookups.py +54 -0
- hare/dialects/postgresql/lookups/ltree/postgresql_ltree_lookups.py +35 -0
- hare/dialects/postgresql/lookups/multiranges/__init__.py +9 -0
- hare/dialects/postgresql/lookups/multiranges/postgresql_multi_range_field_lookups.py +50 -0
- hare/dialects/postgresql/lookups/network/__init__.py +1 -0
- hare/dialects/postgresql/lookups/network/postgresql_network_field_lookups.py +46 -0
- hare/dialects/postgresql/lookups/network/postgresql_network_lookups.py +35 -0
- hare/dialects/postgresql/lookups/postgresql_filter_operators.py +96 -0
- hare/dialects/postgresql/lookups/postgresql_regex_lookups.py +22 -0
- hare/dialects/postgresql/lookups/postgresql_value_encoders.py +163 -0
- hare/dialects/postgresql/lookups/ranges/__init__.py +9 -0
- hare/dialects/postgresql/lookups/ranges/postgresql_range_field_lookups.py +49 -0
- hare/dialects/postgresql/lookups/ranges/postgresql_range_lookups.py +49 -0
- hare/dialects/postgresql/lookups/trigram/__init__.py +1 -0
- hare/dialects/postgresql/lookups/trigram/postgresql_trigram_lookups.py +69 -0
- hare/dialects/postgresql/lookups/trigram/trigram_operator_term.py +16 -0
- hare/dialects/postgresql/lookups/unaccent_transform.py +39 -0
- hare/dialects/postgresql/migration_safety/__init__.py +9 -0
- hare/dialects/postgresql/migration_safety/check_constraint_validation_rule.py +36 -0
- hare/dialects/postgresql/migration_safety/constants.py +18 -0
- hare/dialects/postgresql/migration_safety/foreign_key_validation_rule.py +74 -0
- hare/dialects/postgresql/migration_safety/index_without_concurrently_rule.py +45 -0
- hare/dialects/postgresql/migration_safety/postgresql_migration_safety_rules.py +59 -0
- hare/dialects/postgresql/migration_safety/set_not_null_rule.py +47 -0
- hare/dialects/postgresql/migration_safety/unique_constraint_index_rule.py +65 -0
- hare/dialects/postgresql/migration_safety/volatile_default_rule.py +40 -0
- hare/dialects/postgresql/parameters/__init__.py +1 -0
- hare/dialects/postgresql/parameters/constants.py +83 -0
- hare/dialects/postgresql/parameters/postgresql_parameters.py +86 -0
- hare/dialects/postgresql/partitioning/__init__.py +23 -0
- hare/dialects/postgresql/partitioning/constants.py +56 -0
- hare/dialects/postgresql/partitioning/explicit_partitioning.py +97 -0
- hare/dialects/postgresql/partitioning/hash_partitioning.py +50 -0
- hare/dialects/postgresql/partitioning/list_partitioning.py +55 -0
- hare/dialects/postgresql/partitioning/observed_partitioning.py +205 -0
- hare/dialects/postgresql/partitioning/partitioning.py +280 -0
- hare/dialects/postgresql/partitioning/partitions/__init__.py +1 -0
- hare/dialects/postgresql/partitioning/partitions/default_partition.py +30 -0
- hare/dialects/postgresql/partitioning/partitions/list_partition.py +36 -0
- hare/dialects/postgresql/partitioning/partitions/partition.py +46 -0
- hare/dialects/postgresql/partitioning/partitions/range_partition.py +94 -0
- hare/dialects/postgresql/partitioning/range_partitioning.py +60 -0
- hare/dialects/postgresql/postgresql_dialect.py +207 -0
- hare/dialects/postgresql/postgresql_introspector.py +1055 -0
- hare/dialects/postgresql/postgresql_table_options.py +165 -0
- hare/dialects/postgresql/query/__init__.py +7 -0
- hare/dialects/postgresql/query/declarations.py +13 -0
- hare/dialects/postgresql/renderers/__init__.py +7 -0
- hare/dialects/postgresql/renderers/constants.py +43 -0
- hare/dialects/postgresql/renderers/postgresql_container_renderers.py +90 -0
- hare/dialects/postgresql/renderers/postgresql_defaults.py +88 -0
- hare/dialects/postgresql/renderers/postgresql_json_renderers.py +57 -0
- hare/dialects/postgresql/renderers/postgresql_number_renderers.py +58 -0
- hare/dialects/postgresql/renderers/postgresql_renderers.py +82 -0
- hare/dialects/postgresql/renderers/postgresql_temporal_renderers.py +179 -0
- hare/dialects/postgresql/renderers/postgresql_text_renderers.py +67 -0
- hare/dialects/postgresql/request_query/__init__.py +8 -0
- hare/dialects/postgresql/request_query/declarations.py +17 -0
- hare/dialects/postgresql/schema/__init__.py +0 -0
- hare/dialects/postgresql/schema/columns/__init__.py +1 -0
- hare/dialects/postgresql/schema/columns/postgresql_column_backfill.py +13 -0
- hare/dialects/postgresql/schema/columns/postgresql_column_narrowing_check.py +42 -0
- hare/dialects/postgresql/schema/columns/postgresql_column_type_changes.py +129 -0
- hare/dialects/postgresql/schema/constants.py +384 -0
- hare/dialects/postgresql/schema/constraints/__init__.py +1 -0
- hare/dialects/postgresql/schema/constraints/postgresql_constraint_statements.py +119 -0
- hare/dialects/postgresql/schema/indexes/__init__.py +1 -0
- hare/dialects/postgresql/schema/indexes/postgresql_index_statements.py +24 -0
- hare/dialects/postgresql/schema/postgresql_schema_editor.py +280 -0
- hare/dialects/postgresql/schema/relations/__init__.py +1 -0
- hare/dialects/postgresql/schema/relations/postgresql_foreign_key_rebuild.py +230 -0
- hare/dialects/postgresql/schema/runtime_statements/__init__.py +1 -0
- hare/dialects/postgresql/schema/runtime_statements/postgresql_foreign_key_deferral.py +109 -0
- hare/dialects/postgresql/schema/runtime_statements/postgresql_table_clearing.py +80 -0
- hare/dialects/postgresql/schema/runtime_statements/postgresql_table_locks.py +27 -0
- hare/dialects/postgresql/schema/runtime_statements/postgresql_tenant_conditions.py +34 -0
- hare/dialects/postgresql/schema/schema_objects/__init__.py +1 -0
- hare/dialects/postgresql/schema/schema_objects/postgresql_database_functions.py +95 -0
- hare/dialects/postgresql/schema/schema_objects/postgresql_enum_types.py +130 -0
- hare/dialects/postgresql/schema/schema_objects/postgresql_extensions.py +35 -0
- hare/dialects/postgresql/schema/schema_objects/postgresql_grants.py +89 -0
- hare/dialects/postgresql/schema/schema_objects/postgresql_materialized_views.py +107 -0
- hare/dialects/postgresql/schema/schema_objects/postgresql_row_level_security_policies.py +125 -0
- hare/dialects/postgresql/schema/schema_objects/postgresql_schemas.py +51 -0
- hare/dialects/postgresql/schema/schema_objects/postgresql_sequences.py +132 -0
- hare/dialects/postgresql/schema/schema_objects/postgresql_views.py +53 -0
- hare/dialects/postgresql/schema/shadow/__init__.py +0 -0
- hare/dialects/postgresql/schema/shadow/postgresql_shadow_database.py +78 -0
- hare/dialects/postgresql/schema/tables/__init__.py +1 -0
- hare/dialects/postgresql/schema/tables/postgresql_table_comments.py +74 -0
- hare/dialects/postgresql/schema/tables/postgresql_table_partitions.py +229 -0
- hare/dialects/postgresql/schema/tables/postgresql_table_rebuild.py +118 -0
- hare/dialects/postgresql/schema/triggers/__init__.py +1 -0
- hare/dialects/postgresql/schema/triggers/postgresql_trigger_statements.py +141 -0
- hare/dialects/postgresql/search/__init__.py +8 -0
- hare/dialects/postgresql/search/constants.py +43 -0
- hare/dialects/postgresql/search/criterion/__init__.py +14 -0
- hare/dialects/postgresql/search/criterion/declarations.py +14 -0
- hare/dialects/postgresql/search/criterion/search_criterion.py +62 -0
- hare/dialects/postgresql/search/criterion/ts_query_function.py +20 -0
- hare/dialects/postgresql/search/criterion/ts_query_invert.py +32 -0
- hare/dialects/postgresql/search/enums.py +12 -0
- hare/dialects/postgresql/search/functions/__init__.py +9 -0
- hare/dialects/postgresql/search/functions/plain_to_ts_query.py +18 -0
- hare/dialects/postgresql/search/functions/to_ts_vector.py +20 -0
- hare/dialects/postgresql/search/lexemes/__init__.py +1 -0
- hare/dialects/postgresql/search/lexemes/combined_lexeme.py +35 -0
- hare/dialects/postgresql/search/lexemes/lexeme.py +77 -0
- hare/dialects/postgresql/search/lexemes/lexeme_combinable.py +59 -0
- hare/dialects/postgresql/search/postgresql_text_search.py +237 -0
- hare/dialects/postgresql/search/ts_vector_expression_reader.py +106 -0
- hare/dialects/postgresql/server_versions.py +26 -0
- hare/dialects/postgresql/spatial/__init__.py +7 -0
- hare/dialects/postgresql/spatial/constants.py +118 -0
- hare/dialects/postgresql/spatial/postgresql_spatial_renderers.py +102 -0
- hare/dialects/postgresql/transactions/__init__.py +1 -0
- hare/dialects/postgresql/transactions/constants.py +21 -0
- hare/dialects/postgresql/transactions/postgresql_transaction_statements.py +40 -0
- hare/dialects/postgresql/transactions/postgresql_two_phase_commit.py +87 -0
- hare/dialects/postgresql/types/__init__.py +1 -0
- hare/dialects/postgresql/types/postgresql_container_values.py +104 -0
- hare/dialects/postgresql/types/postgresql_types.py +213 -0
- hare/dialects/postgresql/validators/__init__.py +15 -0
- hare/dialects/postgresql/validators/keys_validator.py +32 -0
- hare/dialects/postgresql/validators/range_bound_validator.py +33 -0
- hare/dialects/postgresql/validators/range_max_value_validator.py +17 -0
- hare/dialects/postgresql/validators/range_min_value_validator.py +17 -0
- hare/dialects/postgresql/vectors/__init__.py +1 -0
- hare/dialects/postgresql/vectors/constants.py +13 -0
- hare/dialects/postgresql/vectors/postgresql_vector_renderers.py +40 -0
- hare/dialects/postgresql/vectors/postgresql_vector_values.py +94 -0
- hare/dialects/sqlite/__init__.py +0 -0
- hare/dialects/sqlite/clauses/__init__.py +1 -0
- hare/dialects/sqlite/clauses/constants.py +7 -0
- hare/dialects/sqlite/clauses/sqlite_query_clauses.py +100 -0
- hare/dialects/sqlite/client/__init__.py +12 -0
- hare/dialects/sqlite/client/constants.py +103 -0
- hare/dialects/sqlite/client/declarations.py +27 -0
- hare/dialects/sqlite/client/sqlite_client.py +507 -0
- hare/dialects/sqlite/client/sqlite_migration_lock.py +76 -0
- hare/dialects/sqlite/client/sqlite_transaction_client.py +160 -0
- hare/dialects/sqlite/connection/__init__.py +1 -0
- hare/dialects/sqlite/connection/constants.py +7 -0
- hare/dialects/sqlite/connection/sqlite_driver.py +59 -0
- hare/dialects/sqlite/constants.py +451 -0
- hare/dialects/sqlite/drivers/__init__.py +1 -0
- hare/dialects/sqlite/drivers/aiosqlite/__init__.py +1 -0
- hare/dialects/sqlite/drivers/aiosqlite/aiosqlite_driver.py +41 -0
- hare/dialects/sqlite/drivers/aiosqlite/client/__init__.py +23 -0
- hare/dialects/sqlite/drivers/aiosqlite/client/aiosqlite_client.py +428 -0
- hare/dialects/sqlite/drivers/aiosqlite/client/aiosqlite_client_with_regexp_support.py +16 -0
- hare/dialects/sqlite/drivers/aiosqlite/client/aiosqlite_connection_wrapper.py +62 -0
- hare/dialects/sqlite/drivers/aiosqlite/client/aiosqlite_statement_timeout_connection_wrapper.py +53 -0
- hare/dialects/sqlite/drivers/aiosqlite/client/aiosqlite_transaction_client.py +176 -0
- hare/dialects/sqlite/drivers/aiosqlite/client/aiosqlite_transaction_connection_wrapper.py +23 -0
- hare/dialects/sqlite/drivers/aiosqlite/constants.py +11 -0
- hare/dialects/sqlite/drivers/constants.py +19 -0
- hare/dialects/sqlite/enums.py +37 -0
- hare/dialects/sqlite/exceptions.py +10 -0
- hare/dialects/sqlite/functions/__init__.py +0 -0
- hare/dialects/sqlite/functions/comparison/__init__.py +11 -0
- hare/dialects/sqlite/functions/comparison/sqlite_cast.py +204 -0
- hare/dialects/sqlite/functions/comparison/sqlite_greatest_least.py +63 -0
- hare/dialects/sqlite/functions/constants.py +102 -0
- hare/dialects/sqlite/functions/datetime/__init__.py +13 -0
- hare/dialects/sqlite/functions/datetime/date_truncation.py +115 -0
- hare/dialects/sqlite/functions/datetime/sqlite_date_part_extraction.py +77 -0
- hare/dialects/sqlite/functions/datetime/sqlite_date_timestamp.py +48 -0
- hare/dialects/sqlite/functions/datetime/sqlite_local_now.py +54 -0
- hare/dialects/sqlite/functions/datetime/temporal_arithmetic_functions.py +147 -0
- hare/dialects/sqlite/functions/decimal/__init__.py +1 -0
- hare/dialects/sqlite/functions/decimal/sqlite_decimal_arithmetic.py +152 -0
- hare/dialects/sqlite/functions/decimal/sqlite_decimal_average.py +23 -0
- hare/dialects/sqlite/functions/decimal/sqlite_decimal_collation.py +125 -0
- hare/dialects/sqlite/functions/decimal/sqlite_decimal_comparand.py +23 -0
- hare/dialects/sqlite/functions/decimal/sqlite_decimal_operation.py +33 -0
- hare/dialects/sqlite/functions/decimal/sqlite_decimal_round.py +50 -0
- hare/dialects/sqlite/functions/decimal/sqlite_decimal_storage.py +77 -0
- hare/dialects/sqlite/functions/decimal/sqlite_decimal_sum.py +62 -0
- hare/dialects/sqlite/functions/decimal/sqlite_decimal_text.py +22 -0
- hare/dialects/sqlite/functions/decimal/sqlite_stored_decimal.py +29 -0
- hare/dialects/sqlite/functions/json/__init__.py +9 -0
- hare/dialects/sqlite/functions/json/sqlite_json_datetime.py +124 -0
- hare/dialects/sqlite/functions/json/sqlite_json_path.py +116 -0
- hare/dialects/sqlite/functions/regex/__init__.py +5 -0
- hare/dialects/sqlite/functions/regex/sqlite_posix_regex.py +102 -0
- hare/dialects/sqlite/functions/regex/sqlite_regex_criterion.py +18 -0
- hare/dialects/sqlite/functions/sqlite_checked_integer.py +15 -0
- hare/dialects/sqlite/functions/sqlite_collation.py +51 -0
- hare/dialects/sqlite/functions/sqlite_connection_function.py +17 -0
- hare/dialects/sqlite/functions/sqlite_function_errors.py +45 -0
- hare/dialects/sqlite/functions/sqlite_integer_range.py +48 -0
- hare/dialects/sqlite/functions/sqlite_math_functions.py +233 -0
- hare/dialects/sqlite/functions/sqlite_native_functions.py +12 -0
- hare/dialects/sqlite/functions/sqlite_sort_keys.py +58 -0
- hare/dialects/sqlite/functions/statistics/__init__.py +19 -0
- hare/dialects/sqlite/functions/statistics/declarations.py +31 -0
- hare/dialects/sqlite/functions/statistics/sqlite_statistic.py +118 -0
- hare/dialects/sqlite/functions/statistics/sqlite_statistics.py +51 -0
- hare/dialects/sqlite/functions/text/__init__.py +1 -0
- hare/dialects/sqlite/functions/text/sqlite_text_functions.py +140 -0
- hare/dialects/sqlite/indexes/__init__.py +7 -0
- hare/dialects/sqlite/indexes/constants.py +45 -0
- hare/dialects/sqlite/indexes/full_text_index.py +228 -0
- hare/dialects/sqlite/indexes/separate_table_index.py +105 -0
- hare/dialects/sqlite/indexes/spatialite_index.py +228 -0
- hare/dialects/sqlite/literals/__init__.py +1 -0
- hare/dialects/sqlite/literals/sqlite_literals.py +51 -0
- hare/dialects/sqlite/lookups/__init__.py +0 -0
- hare/dialects/sqlite/lookups/constants.py +18 -0
- hare/dialects/sqlite/lookups/in_list/__init__.py +11 -0
- hare/dialects/sqlite/lookups/in_list/json_array_row_values.py +39 -0
- hare/dialects/sqlite/lookups/in_list/json_array_values.py +116 -0
- hare/dialects/sqlite/lookups/in_list/sqlite_large_in_list.py +96 -0
- hare/dialects/sqlite/lookups/json/__init__.py +1 -0
- hare/dialects/sqlite/lookups/json/sqlite_json_filter_guards.py +128 -0
- hare/dialects/sqlite/lookups/json/sqlite_json_lookups.py +51 -0
- hare/dialects/sqlite/lookups/json/sqlite_json_path_lookups.py +56 -0
- hare/dialects/sqlite/lookups/json/sqlite_json_type_criterion.py +13 -0
- hare/dialects/sqlite/lookups/sqlite_filter_operators.py +89 -0
- hare/dialects/sqlite/migration_safety/__init__.py +9 -0
- hare/dialects/sqlite/migration_safety/sqlite_migration_safety_rules.py +32 -0
- hare/dialects/sqlite/parameters/__init__.py +1 -0
- hare/dialects/sqlite/parameters/constants.py +11 -0
- hare/dialects/sqlite/parameters/sqlite_parameter_adapters.py +61 -0
- hare/dialects/sqlite/parameters/sqlite_parameters.py +27 -0
- hare/dialects/sqlite/query/__init__.py +7 -0
- hare/dialects/sqlite/query/declarations.py +13 -0
- hare/dialects/sqlite/renderers/__init__.py +7 -0
- hare/dialects/sqlite/renderers/constants.py +43 -0
- hare/dialects/sqlite/renderers/sqlite_defaults.py +84 -0
- hare/dialects/sqlite/renderers/sqlite_json_renderers.py +142 -0
- hare/dialects/sqlite/renderers/sqlite_number_renderers.py +137 -0
- hare/dialects/sqlite/renderers/sqlite_renderers.py +235 -0
- hare/dialects/sqlite/renderers/sqlite_temporal_renderers.py +138 -0
- hare/dialects/sqlite/renderers/sqlite_text_renderers.py +60 -0
- hare/dialects/sqlite/request_query/__init__.py +8 -0
- hare/dialects/sqlite/request_query/declarations.py +16 -0
- hare/dialects/sqlite/schema/__init__.py +0 -0
- hare/dialects/sqlite/schema/columns/__init__.py +1 -0
- hare/dialects/sqlite/schema/columns/sqlite_column_backfill.py +29 -0
- hare/dialects/sqlite/schema/columns/sqlite_column_conversion_check.py +181 -0
- hare/dialects/sqlite/schema/columns/sqlite_column_narrowing_check.py +24 -0
- hare/dialects/sqlite/schema/columns/sqlite_column_type_changes.py +148 -0
- hare/dialects/sqlite/schema/constants.py +108 -0
- hare/dialects/sqlite/schema/constraints/__init__.py +1 -0
- hare/dialects/sqlite/schema/constraints/sqlite_constraint_statements.py +32 -0
- hare/dialects/sqlite/schema/indexes/__init__.py +1 -0
- hare/dialects/sqlite/schema/indexes/sqlite_generated_index_names.py +61 -0
- hare/dialects/sqlite/schema/indexes/sqlite_index_statements.py +78 -0
- hare/dialects/sqlite/schema/relations/__init__.py +1 -0
- hare/dialects/sqlite/schema/relations/sqlite_foreign_key_rebuild.py +100 -0
- hare/dialects/sqlite/schema/runtime_statements/__init__.py +1 -0
- hare/dialects/sqlite/schema/runtime_statements/sqlite_foreign_key_deferral.py +87 -0
- hare/dialects/sqlite/schema/runtime_statements/sqlite_table_clearing.py +39 -0
- hare/dialects/sqlite/schema/runtime_statements/sqlite_tenant_conditions.py +21 -0
- hare/dialects/sqlite/schema/shadow/__init__.py +0 -0
- hare/dialects/sqlite/schema/shadow/sqlite_shadow_database.py +36 -0
- hare/dialects/sqlite/schema/sqlite_schema_editor.py +492 -0
- hare/dialects/sqlite/schema/tables/__init__.py +1 -0
- hare/dialects/sqlite/schema/tables/sqlite_table_comments.py +32 -0
- hare/dialects/sqlite/schema/tables/sqlite_table_rebuild.py +164 -0
- hare/dialects/sqlite/schema/triggers/__init__.py +1 -0
- hare/dialects/sqlite/schema/triggers/sqlite_trigger_statements.py +70 -0
- hare/dialects/sqlite/search/__init__.py +8 -0
- hare/dialects/sqlite/search/constants.py +33 -0
- hare/dialects/sqlite/search/sqlite_full_text_query.py +137 -0
- hare/dialects/sqlite/search/sqlite_search_renderers.py +33 -0
- hare/dialects/sqlite/search/sqlite_text_search.py +308 -0
- hare/dialects/sqlite/search/terms/__init__.py +1 -0
- hare/dialects/sqlite/search/terms/full_text_headline.py +56 -0
- hare/dialects/sqlite/search/terms/full_text_match.py +73 -0
- hare/dialects/sqlite/search/terms/full_text_query.py +42 -0
- hare/dialects/sqlite/search/terms/full_text_query_combination.py +82 -0
- hare/dialects/sqlite/search/terms/full_text_rank.py +34 -0
- hare/dialects/sqlite/search/terms/full_text_row_value.py +104 -0
- hare/dialects/sqlite/server_versions.py +17 -0
- hare/dialects/sqlite/spatial/__init__.py +0 -0
- hare/dialects/sqlite/spatial/constants.py +173 -0
- hare/dialects/sqlite/spatial/spatialite_blob_reader.py +166 -0
- hare/dialects/sqlite/spatial/spatialite_blob_writer.py +105 -0
- hare/dialects/sqlite/spatial/sqlite_geometry_values.py +75 -0
- hare/dialects/sqlite/spatial/sqlite_spatial_extension.py +116 -0
- hare/dialects/sqlite/spatial/sqlite_spatial_renderers.py +202 -0
- hare/dialects/sqlite/sqlite_dialect.py +138 -0
- hare/dialects/sqlite/sqlite_introspector.py +1025 -0
- hare/dialects/sqlite/sqlite_table_options.py +92 -0
- hare/dialects/sqlite/table_option_constants.py +15 -0
- hare/dialects/sqlite/transactions/__init__.py +1 -0
- hare/dialects/sqlite/transactions/constants.py +10 -0
- hare/dialects/sqlite/transactions/sqlite_transaction_statements.py +19 -0
- hare/dialects/sqlite/types/__init__.py +1 -0
- hare/dialects/sqlite/types/sqlite_types.py +87 -0
- hare/dialects/sqlite/vectors/__init__.py +1 -0
- hare/dialects/sqlite/vectors/constants.py +16 -0
- hare/dialects/sqlite/vectors/sqlite_vector_extension.py +112 -0
- hare/dialects/sqlite/vectors/sqlite_vector_renderers.py +55 -0
- hare/dialects/sqlite/vectors/sqlite_vector_values.py +113 -0
- hare/exceptions.py +397 -0
- hare/fields/__init__.py +133 -0
- hare/fields/composite_primary_key.py +40 -0
- hare/fields/constants.py +120 -0
- hare/fields/data/__init__.py +3 -0
- hare/fields/data/binary_field.py +62 -0
- hare/fields/data/boolean_field.py +57 -0
- hare/fields/data/choices/__init__.py +16 -0
- hare/fields/data/choices/char_enum_field.py +27 -0
- hare/fields/data/choices/char_enum_field_instance.py +117 -0
- hare/fields/data/choices/int_enum_field.py +23 -0
- hare/fields/data/choices/int_enum_field_instance.py +102 -0
- hare/fields/data/constants.py +122 -0
- hare/fields/data/containers/__init__.py +10 -0
- hare/fields/data/containers/array_field.py +152 -0
- hare/fields/data/containers/constants.py +25 -0
- hare/fields/data/containers/container_field.py +342 -0
- hare/fields/data/containers/declarations.py +13 -0
- hare/fields/data/containers/map_field.py +165 -0
- hare/fields/data/containers/nested_field.py +47 -0
- hare/fields/data/containers/tuple_field.py +177 -0
- hare/fields/data/json/__init__.py +7 -0
- hare/fields/data/json/json_codec.py +152 -0
- hare/fields/data/json/json_field.py +387 -0
- hare/fields/data/json/json_path_field.py +77 -0
- hare/fields/data/json/json_text_field.py +13 -0
- hare/fields/data/network/__init__.py +8 -0
- hare/fields/data/network/constants.py +6 -0
- hare/fields/data/network/ip_address_field.py +109 -0
- hare/fields/data/network/ipv4_address_field.py +26 -0
- hare/fields/data/numeric/__init__.py +23 -0
- hare/fields/data/numeric/big_int_field.py +22 -0
- hare/fields/data/numeric/decimal_field.py +187 -0
- hare/fields/data/numeric/float_field.py +83 -0
- hare/fields/data/numeric/int_field.py +239 -0
- hare/fields/data/numeric/positive_big_int_field.py +19 -0
- hare/fields/data/numeric/positive_int_field.py +19 -0
- hare/fields/data/numeric/positive_small_int_field.py +19 -0
- hare/fields/data/numeric/small_int_field.py +22 -0
- hare/fields/data/temporal/__init__.py +11 -0
- hare/fields/data/temporal/date_field.py +87 -0
- hare/fields/data/temporal/datetime_field.py +384 -0
- hare/fields/data/temporal/parse_datetime.py +17 -0
- hare/fields/data/temporal/temporal_values.py +119 -0
- hare/fields/data/temporal/time_delta_field.py +111 -0
- hare/fields/data/temporal/time_field.py +193 -0
- hare/fields/data/text/__init__.py +20 -0
- hare/fields/data/text/char_field.py +78 -0
- hare/fields/data/text/email_field.py +76 -0
- hare/fields/data/text/phone_field.py +114 -0
- hare/fields/data/text/slug_field.py +52 -0
- hare/fields/data/text/text_field.py +33 -0
- hare/fields/data/text/text_values.py +39 -0
- hare/fields/data/text/url_field.py +62 -0
- hare/fields/data/uuid_field.py +82 -0
- hare/fields/database_default.py +28 -0
- hare/fields/db_default_not_set.py +36 -0
- hare/fields/db_defaults/__init__.py +13 -0
- hare/fields/db_defaults/now.py +108 -0
- hare/fields/db_defaults/random_hex.py +30 -0
- hare/fields/db_defaults/sql_default.py +95 -0
- hare/fields/db_defaults/uuid_v7.py +36 -0
- hare/fields/encrypted/__init__.py +7 -0
- hare/fields/encrypted/blind_index_field.py +49 -0
- hare/fields/encrypted/constants.py +41 -0
- hare/fields/encrypted/encrypted_field_base.py +143 -0
- hare/fields/encrypted/encrypted_json_field.py +238 -0
- hare/fields/encrypted/encrypted_text_field.py +130 -0
- hare/fields/encrypted/field_encryption.py +267 -0
- hare/fields/enums.py +91 -0
- hare/fields/field.py +1231 -0
- hare/fields/field_meta.py +16 -0
- hare/fields/generated_field.py +211 -0
- hare/fields/narrowing/__init__.py +7 -0
- hare/fields/narrowing/decimal_digits_limit.py +11 -0
- hare/fields/narrowing/enum_values_limit.py +32 -0
- hare/fields/narrowing/integer_range_limit.py +13 -0
- hare/fields/narrowing/narrowing_limit.py +8 -0
- hare/fields/narrowing/text_length_limit.py +13 -0
- hare/fields/registrations/__init__.py +1 -0
- hare/fields/registrations/registered_lookup.py +29 -0
- hare/fields/registrations/registered_transform.py +22 -0
- hare/fields/relations/__init__.py +3 -0
- hare/fields/relations/constants.py +10 -0
- hare/fields/relations/declarations.py +5 -0
- hare/fields/relations/fields/__init__.py +35 -0
- hare/fields/relations/fields/backward_foreign_key_relation.py +46 -0
- hare/fields/relations/fields/declarations.py +21 -0
- hare/fields/relations/fields/foreign_key_field.py +89 -0
- hare/fields/relations/fields/foreign_key_field_instance.py +124 -0
- hare/fields/relations/fields/generic_foreign_key_field.py +56 -0
- hare/fields/relations/fields/generic_foreign_key_field_instance.py +455 -0
- hare/fields/relations/fields/many_to_many_field.py +60 -0
- hare/fields/relations/fields/many_to_many_field_instance.py +126 -0
- hare/fields/relations/fields/one_to_one_field.py +89 -0
- hare/fields/relations/fields/one_to_one_field_instance.py +45 -0
- hare/fields/relations/fields/relational_field.py +153 -0
- hare/fields/relations/inherited_relation.py +30 -0
- hare/fields/relations/relation_accessors.py +271 -0
- hare/fields/relations/relation_values.py +106 -0
- hare/fields/relations/swappable_model_reference.py +60 -0
- hare/fields/validators/__init__.py +63 -0
- hare/fields/validators/exceptions.py +52 -0
- hare/fields/validators/formats/__init__.py +1 -0
- hare/fields/validators/formats/comma_separated_integer_list_validator.py +22 -0
- hare/fields/validators/formats/domain_name_validator.py +74 -0
- hare/fields/validators/formats/e164_phone_validator.py +32 -0
- hare/fields/validators/formats/email_validator.py +87 -0
- hare/fields/validators/formats/ipv46_validator.py +28 -0
- hare/fields/validators/formats/ipv4_validator.py +23 -0
- hare/fields/validators/formats/ipv6_validator.py +23 -0
- hare/fields/validators/formats/regex_validator.py +38 -0
- hare/fields/validators/formats/slug_validator.py +36 -0
- hare/fields/validators/formats/url_validator.py +95 -0
- hare/fields/validators/limits/__init__.py +1 -0
- hare/fields/validators/limits/length_validator.py +17 -0
- hare/fields/validators/limits/max_digits_validator.py +58 -0
- hare/fields/validators/limits/max_length_validator.py +20 -0
- hare/fields/validators/limits/max_value_validator.py +19 -0
- hare/fields/validators/limits/min_length_validator.py +20 -0
- hare/fields/validators/limits/min_value_validator.py +19 -0
- hare/fields/validators/limits/numeric_validator.py +19 -0
- hare/fields/validators/validator.py +34 -0
- hare/gis/__init__.py +52 -0
- hare/gis/aggregates/__init__.py +5 -0
- hare/gis/aggregates/declarations.py +42 -0
- hare/gis/aggregates/spatial_aggregate.py +57 -0
- hare/gis/constants.py +126 -0
- hare/gis/enums.py +74 -0
- hare/gis/fields/__init__.py +23 -0
- hare/gis/fields/declarations.py +61 -0
- hare/gis/fields/extent_field.py +60 -0
- hare/gis/fields/geometry_field.py +239 -0
- hare/gis/fields/made_line_field.py +86 -0
- hare/gis/functions/__init__.py +53 -0
- hare/gis/functions/buffer.py +29 -0
- hare/gis/functions/constants.py +17 -0
- hare/gis/functions/declarations.py +188 -0
- hare/gis/functions/simplify.py +29 -0
- hare/gis/functions/spatial_function.py +115 -0
- hare/gis/functions/transform.py +41 -0
- hare/gis/geometries/__init__.py +19 -0
- hare/gis/geometries/declarations.py +38 -0
- hare/gis/geometries/geometry.py +297 -0
- hare/gis/geometries/geometry_collection.py +62 -0
- hare/gis/geometries/line_string.py +46 -0
- hare/gis/geometries/multi_geometry.py +75 -0
- hare/gis/geometries/point.py +65 -0
- hare/gis/geometries/polygon.py +89 -0
- hare/gis/lookups/__init__.py +3 -0
- hare/gis/lookups/spatial_field_lookups.py +219 -0
- hare/gis/readers/__init__.py +11 -0
- hare/gis/readers/constants.py +15 -0
- hare/gis/readers/ewkb_reader.py +148 -0
- hare/gis/readers/geo_json_reader.py +54 -0
- hare/gis/readers/wkt_reader.py +226 -0
- hare/gis/spatial_features.py +57 -0
- hare/gis/terms/__init__.py +11 -0
- hare/gis/terms/geometry_value.py +33 -0
- hare/gis/terms/spatial_aggregate_function.py +30 -0
- hare/gis/terms/spatial_function_term.py +39 -0
- hare/gis/terms/spatial_relation_term.py +39 -0
- hare/health/__init__.py +19 -0
- hare/health/constants.py +32 -0
- hare/health/criteria/__init__.py +27 -0
- hare/health/criteria/acquire_wait_time.py +35 -0
- hare/health/criteria/all_of.py +38 -0
- hare/health/criteria/declarations.py +33 -0
- hare/health/criteria/health_criterion.py +87 -0
- hare/health/criteria/ping_failed.py +27 -0
- hare/health/criteria/ping_latency.py +29 -0
- hare/health/criteria/pool_count_criterion.py +37 -0
- hare/health/criteria/pool_saturation.py +35 -0
- hare/health/criteria/waiting_requests.py +33 -0
- hare/health/declarations.py +83 -0
- hare/health/enums.py +14 -0
- hare/health/health_check.py +240 -0
- hare/health/health_report.py +65 -0
- hare/inspectdb/__init__.py +38 -0
- hare/inspectdb/constants.py +60 -0
- hare/inspectdb/exceptions.py +72 -0
- hare/inspectdb/generation/__init__.py +1 -0
- hare/inspectdb/generation/column_type_mapper.py +113 -0
- hare/inspectdb/generation/declarations.py +34 -0
- hare/inspectdb/generation/inspected_model.py +35 -0
- hare/inspectdb/generation/inspected_model_builder.py +1174 -0
- hare/inspectdb/generation/many_to_many_tables.py +91 -0
- hare/inspectdb/generation/model_factory.py +88 -0
- hare/inspectdb/generation/model_naming.py +75 -0
- hare/inspectdb/generation/model_source_builder.py +148 -0
- hare/inspectdb/introspection/__init__.py +28 -0
- hare/inspectdb/introspection/column_info.py +67 -0
- hare/inspectdb/introspection/composite_foreign_key_info.py +27 -0
- hare/inspectdb/introspection/database_catalog.py +252 -0
- hare/inspectdb/introspection/enums.py +26 -0
- hare/inspectdb/introspection/foreign_key_info.py +25 -0
- hare/inspectdb/introspection/index_info.py +265 -0
- hare/inspectdb/introspection/inspected_field_specification.py +47 -0
- hare/inspectdb/introspection/schema_introspector.py +564 -0
- hare/inspectdb/introspection/schema_part.py +103 -0
- hare/inspectdb/introspection/table_info.py +112 -0
- hare/inspectdb/introspection/table_parts.py +101 -0
- hare/inspectdb/schema_inspector.py +224 -0
- hare/instrumentation/__init__.py +31 -0
- hare/instrumentation/capture/__init__.py +9 -0
- hare/instrumentation/capture/capture_needs.py +54 -0
- hare/instrumentation/capture/captured_change.py +38 -0
- hare/instrumentation/capture/captured_write.py +223 -0
- hare/instrumentation/capture/change_capturing.py +496 -0
- hare/instrumentation/capture/change_sink.py +57 -0
- hare/instrumentation/change_events.py +246 -0
- hare/instrumentation/constants.py +41 -0
- hare/instrumentation/declarations.py +196 -0
- hare/instrumentation/enums.py +35 -0
- hare/instrumentation/observers/__init__.py +1 -0
- hare/instrumentation/observers/observer.py +56 -0
- hare/instrumentation/observers/observer_dispatch.py +197 -0
- hare/instrumentation/observers/observer_set.py +138 -0
- hare/instrumentation/observers/observers.py +368 -0
- hare/instrumentation/pools/__init__.py +1 -0
- hare/instrumentation/pools/duration_records.py +50 -0
- hare/instrumentation/pools/pool_metrics.py +50 -0
- hare/instrumentation/pools/pool_registry.py +49 -0
- hare/instrumentation/queries/__init__.py +1 -0
- hare/instrumentation/queries/query_tags.py +133 -0
- hare/instrumentation/queries/query_wrapper.py +37 -0
- hare/lazy_loading/__init__.py +1 -0
- hare/lazy_loading/lazy_pattern.py +45 -0
- hare/lazy_loading/pydantic_classes.py +96 -0
- hare/migrations/__init__.py +90 -0
- hare/migrations/api/__init__.py +24 -0
- hare/migrations/api/checkmigrations.py +55 -0
- hare/migrations/api/makemigrations.py +78 -0
- hare/migrations/api/migrate.py +47 -0
- hare/migrations/api/migration_request_parser.py +86 -0
- hare/migrations/api/plan.py +39 -0
- hare/migrations/api/sqlmigrate.py +51 -0
- hare/migrations/api/squashmigrations.py +51 -0
- hare/migrations/autodetection/__init__.py +4 -0
- hare/migrations/autodetection/constants.py +49 -0
- hare/migrations/autodetection/diffs/__init__.py +1 -0
- hare/migrations/autodetection/diffs/constraint_diff.py +48 -0
- hare/migrations/autodetection/diffs/declarations.py +73 -0
- hare/migrations/autodetection/diffs/declared_schema_object_diff.py +47 -0
- hare/migrations/autodetection/diffs/grant_diff.py +24 -0
- hare/migrations/autodetection/diffs/index_diff.py +73 -0
- hare/migrations/autodetection/diffs/materialized_view_diff.py +44 -0
- hare/migrations/autodetection/diffs/partition_diff.py +99 -0
- hare/migrations/autodetection/diffs/schema_object_diff.py +153 -0
- hare/migrations/autodetection/diffs/state_field_diff.py +566 -0
- hare/migrations/autodetection/diffs/state_model_diff.py +355 -0
- hare/migrations/autodetection/diffs/trigger_diff.py +31 -0
- hare/migrations/autodetection/diffs/view_diff.py +24 -0
- hare/migrations/autodetection/field_comparable_values.py +20 -0
- hare/migrations/autodetection/migration_autodetector.py +337 -0
- hare/migrations/autodetection/migration_splitter.py +151 -0
- hare/migrations/autodetection/operation_generator.py +1115 -0
- hare/migrations/autodetection/operation_sorter.py +213 -0
- hare/migrations/autodetection/rename_questions.py +98 -0
- hare/migrations/autodetection/required_extensions.py +118 -0
- hare/migrations/autodetection/schema_object_operations.py +150 -0
- hare/migrations/autodetection/split_migration.py +24 -0
- hare/migrations/autodetection/state_signatures.py +192 -0
- hare/migrations/constants.py +109 -0
- hare/migrations/drift/__init__.py +13 -0
- hare/migrations/drift/column_mismatch.py +14 -0
- hare/migrations/drift/constants.py +43 -0
- hare/migrations/drift/detect_drift.py +40 -0
- hare/migrations/drift/detect_drift_for_alias.py +87 -0
- hare/migrations/drift/drift_result.py +22 -0
- hare/migrations/drift/shadow/__init__.py +0 -0
- hare/migrations/drift/shadow/column_field_names.py +26 -0
- hare/migrations/drift/shadow/schema_comparison.py +557 -0
- hare/migrations/drift/shadow/shadow_drift.py +318 -0
- hare/migrations/drift/shadow/shadow_state.py +83 -0
- hare/migrations/exceptions.py +69 -0
- hare/migrations/execution/__init__.py +3 -0
- hare/migrations/execution/connections_plan.py +192 -0
- hare/migrations/execution/constants.py +4 -0
- hare/migrations/execution/executor/__init__.py +11 -0
- hare/migrations/execution/executor/migration_executor.py +640 -0
- hare/migrations/execution/executor/migration_target.py +9 -0
- hare/migrations/execution/executor/plan_step.py +30 -0
- hare/migrations/execution/migration_runner.py +304 -0
- hare/migrations/execution/swappable_setting_check.py +161 -0
- hare/migrations/loading/__init__.py +4 -0
- hare/migrations/loading/graph/__init__.py +13 -0
- hare/migrations/loading/graph/dummy_node.py +22 -0
- hare/migrations/loading/graph/migration_graph.py +235 -0
- hare/migrations/loading/graph/migration_key.py +14 -0
- hare/migrations/loading/graph/node.py +40 -0
- hare/migrations/loading/migration_loader.py +256 -0
- hare/migrations/loading/migrations_modules.py +207 -0
- hare/migrations/loading/recorder/__init__.py +9 -0
- hare/migrations/loading/recorder/migration_recorder.py +130 -0
- hare/migrations/loading/recorder/noop_recorder.py +26 -0
- hare/migrations/making/__init__.py +1 -0
- hare/migrations/making/declared_attribute_values.py +27 -0
- hare/migrations/making/migration_changes.py +27 -0
- hare/migrations/making/migration_checks.py +115 -0
- hare/migrations/making/migration_maker.py +291 -0
- hare/migrations/making/migration_optimizer.py +70 -0
- hare/migrations/making/migration_squasher.py +193 -0
- hare/migrations/making/squashed_migration.py +24 -0
- hare/migrations/migration.py +341 -0
- hare/migrations/operations/__init__.py +132 -0
- hare/migrations/operations/columns/__init__.py +11 -0
- hare/migrations/operations/columns/alter_column_not_null_safe.py +140 -0
- hare/migrations/operations/columns/backfill_column.py +118 -0
- hare/migrations/operations/constants.py +20 -0
- hare/migrations/operations/constraints/__init__.py +15 -0
- hare/migrations/operations/constraints/add_constraint.py +129 -0
- hare/migrations/operations/constraints/declarations.py +13 -0
- hare/migrations/operations/constraints/rename_constraint.py +21 -0
- hare/migrations/operations/constraints/validate_constraint.py +66 -0
- hare/migrations/operations/database_functions/__init__.py +10 -0
- hare/migrations/operations/database_functions/add_function.py +28 -0
- hare/migrations/operations/database_functions/alter_function.py +30 -0
- hare/migrations/operations/database_functions/remove_function.py +20 -0
- hare/migrations/operations/database_functions/rename_function.py +21 -0
- hare/migrations/operations/declared_uniqueness_checks.py +76 -0
- hare/migrations/operations/dependencies/__init__.py +1 -0
- hare/migrations/operations/dependencies/operation_dependency.py +89 -0
- hare/migrations/operations/dependencies/relation_dependencies.py +157 -0
- hare/migrations/operations/dictionaries/__init__.py +10 -0
- hare/migrations/operations/dictionaries/add_dictionary.py +28 -0
- hare/migrations/operations/dictionaries/alter_dictionary.py +29 -0
- hare/migrations/operations/dictionaries/remove_dictionary.py +20 -0
- hare/migrations/operations/dictionaries/rename_dictionary.py +21 -0
- hare/migrations/operations/enum_types/__init__.py +7 -0
- hare/migrations/operations/enum_types/alter_enum_type.py +64 -0
- hare/migrations/operations/enum_types/create_enum_type.py +57 -0
- hare/migrations/operations/enum_types/drop_enum_type.py +66 -0
- hare/migrations/operations/enum_types/enum_type_operation.py +35 -0
- hare/migrations/operations/enums.py +24 -0
- hare/migrations/operations/extensions/__init__.py +15 -0
- hare/migrations/operations/extensions/create_collation.py +82 -0
- hare/migrations/operations/extensions/create_extension.py +47 -0
- hare/migrations/operations/extensions/remove_collation.py +35 -0
- hare/migrations/operations/extensions/remove_extension.py +40 -0
- hare/migrations/operations/fields/__init__.py +11 -0
- hare/migrations/operations/fields/add_field.py +135 -0
- hare/migrations/operations/fields/alter_field.py +128 -0
- hare/migrations/operations/fields/field_add_remove_operation.py +41 -0
- hare/migrations/operations/fields/field_like.py +14 -0
- hare/migrations/operations/fields/remove_field.py +326 -0
- hare/migrations/operations/fields/rename_field.py +725 -0
- hare/migrations/operations/grants/__init__.py +8 -0
- hare/migrations/operations/grants/add_grant.py +31 -0
- hare/migrations/operations/grants/remove_grant.py +35 -0
- hare/migrations/operations/hare_operation.py +174 -0
- hare/migrations/operations/indexes/__init__.py +13 -0
- hare/migrations/operations/indexes/add_index.py +42 -0
- hare/migrations/operations/indexes/declarations.py +12 -0
- hare/migrations/operations/indexes/remove_index.py +36 -0
- hare/migrations/operations/materialized_views/__init__.py +17 -0
- hare/migrations/operations/materialized_views/add_materialized_view.py +37 -0
- hare/migrations/operations/materialized_views/alter_materialized_view.py +32 -0
- hare/migrations/operations/materialized_views/refresh_materialized_view.py +57 -0
- hare/migrations/operations/materialized_views/remove_materialized_view.py +28 -0
- hare/migrations/operations/materialized_views/rename_materialized_view.py +23 -0
- hare/migrations/operations/model_bound_operation.py +95 -0
- hare/migrations/operations/models/__init__.py +12 -0
- hare/migrations/operations/models/alter_model_options.py +158 -0
- hare/migrations/operations/models/alter_model_schema.py +114 -0
- hare/migrations/operations/models/alter_model_table.py +65 -0
- hare/migrations/operations/models/create_model.py +407 -0
- hare/migrations/operations/models/delete_model.py +122 -0
- hare/migrations/operations/models/model_table_operation.py +45 -0
- hare/migrations/operations/models/rename_model.py +165 -0
- hare/migrations/operations/models/table_renaming_operation.py +101 -0
- hare/migrations/operations/operation.py +252 -0
- hare/migrations/operations/partitions/__init__.py +11 -0
- hare/migrations/operations/partitions/add_partition.py +36 -0
- hare/migrations/operations/partitions/partition_operation.py +93 -0
- hare/migrations/operations/partitions/remove_partition.py +36 -0
- hare/migrations/operations/policies/__init__.py +11 -0
- hare/migrations/operations/policies/add_policy.py +28 -0
- hare/migrations/operations/policies/alter_policy.py +30 -0
- hare/migrations/operations/policies/alter_row_level_security.py +90 -0
- hare/migrations/operations/policies/remove_policy.py +21 -0
- hare/migrations/operations/policies/rename_policy.py +21 -0
- hare/migrations/operations/schema_objects/__init__.py +11 -0
- hare/migrations/operations/schema_objects/add_schema_object.py +103 -0
- hare/migrations/operations/schema_objects/alter_schema_object.py +89 -0
- hare/migrations/operations/schema_objects/object_types/__init__.py +1 -0
- hare/migrations/operations/schema_objects/object_types/constraint_object_type.py +98 -0
- hare/migrations/operations/schema_objects/object_types/dictionary_object_type.py +51 -0
- hare/migrations/operations/schema_objects/object_types/function_object_type.py +55 -0
- hare/migrations/operations/schema_objects/object_types/grant_object_type.py +71 -0
- hare/migrations/operations/schema_objects/object_types/index_object_type.py +140 -0
- hare/migrations/operations/schema_objects/object_types/materialized_view_object_type.py +63 -0
- hare/migrations/operations/schema_objects/object_types/policy_object_type.py +53 -0
- hare/migrations/operations/schema_objects/object_types/schema_object_type.py +234 -0
- hare/migrations/operations/schema_objects/object_types/sequence_object_type.py +54 -0
- hare/migrations/operations/schema_objects/object_types/trigger_object_type.py +46 -0
- hare/migrations/operations/schema_objects/object_types/view_object_type.py +60 -0
- hare/migrations/operations/schema_objects/remove_schema_object.py +105 -0
- hare/migrations/operations/schema_objects/rename_schema_object.py +116 -0
- hare/migrations/operations/schemas/__init__.py +11 -0
- hare/migrations/operations/schemas/create_schema.py +45 -0
- hare/migrations/operations/schemas/drop_schema.py +40 -0
- hare/migrations/operations/sequences/__init__.py +10 -0
- hare/migrations/operations/sequences/add_sequence.py +28 -0
- hare/migrations/operations/sequences/alter_sequence.py +29 -0
- hare/migrations/operations/sequences/remove_sequence.py +20 -0
- hare/migrations/operations/sequences/rename_sequence.py +21 -0
- hare/migrations/operations/special/__init__.py +16 -0
- hare/migrations/operations/special/run_python.py +82 -0
- hare/migrations/operations/special/run_sql.py +107 -0
- hare/migrations/operations/special/separate_database_and_state.py +95 -0
- hare/migrations/operations/special/synchronize_key_series.py +51 -0
- hare/migrations/operations/triggers/__init__.py +15 -0
- hare/migrations/operations/triggers/add_trigger.py +28 -0
- hare/migrations/operations/triggers/alter_trigger.py +28 -0
- hare/migrations/operations/triggers/remove_trigger.py +20 -0
- hare/migrations/operations/triggers/rename_trigger.py +21 -0
- hare/migrations/operations/views/__init__.py +10 -0
- hare/migrations/operations/views/add_view.py +29 -0
- hare/migrations/operations/views/alter_view.py +29 -0
- hare/migrations/operations/views/remove_view.py +20 -0
- hare/migrations/operations/views/rename_view.py +21 -0
- hare/migrations/reports/__init__.py +12 -0
- hare/migrations/reports/operation_effect.py +28 -0
- hare/migrations/reports/operation_plan.py +23 -0
- hare/migrations/runtime_enums.py +88 -0
- hare/migrations/safety/__init__.py +16 -0
- hare/migrations/safety/enums.py +37 -0
- hare/migrations/safety/migration_risk.py +33 -0
- hare/migrations/safety/migration_safety_checker.py +250 -0
- hare/migrations/safety/migration_safety_context.py +142 -0
- hare/migrations/state/__init__.py +11 -0
- hare/migrations/state/model_state.py +359 -0
- hare/migrations/state/state.py +297 -0
- hare/migrations/state/state_apps.py +315 -0
- hare/migrations/state/state_rendering.py +222 -0
- hare/migrations/swappable_dependency.py +36 -0
- hare/migrations/writer/__init__.py +9 -0
- hare/migrations/writer/constants.py +28 -0
- hare/migrations/writer/import_manager.py +106 -0
- hare/migrations/writer/migration_writer.py +986 -0
- hare/models/__init__.py +20 -0
- hare/models/class_building/__init__.py +1 -0
- hare/models/class_building/abstract_meta_inheritance.py +116 -0
- hare/models/class_building/blind_indexes.py +54 -0
- hare/models/class_building/constants.py +61 -0
- hare/models/class_building/extension_model_options.py +20 -0
- hare/models/class_building/field_comments.py +131 -0
- hare/models/class_building/generic_foreign_keys.py +287 -0
- hare/models/class_building/instance_constructors.py +110 -0
- hare/models/class_building/lazy_relation_fields.py +140 -0
- hare/models/class_building/model_definition_checks.py +710 -0
- hare/models/class_building/model_field_collection.py +185 -0
- hare/models/class_building/model_managers.py +62 -0
- hare/models/class_building/primary_key_declaration.py +204 -0
- hare/models/class_building/schema_object_declarations.py +106 -0
- hare/models/constants.py +75 -0
- hare/models/deletion/__init__.py +0 -0
- hare/models/deletion/cascade/__init__.py +1 -0
- hare/models/deletion/cascade/cascade_deletion.py +818 -0
- hare/models/deletion/cascade/cascade_restore.py +150 -0
- hare/models/deletion/cascade/deletion_collector.py +646 -0
- hare/models/deletion/cascade/deletion_graph.py +418 -0
- hare/models/deletion/cascade/deletion_plan.py +94 -0
- hare/models/deletion/cascade/protect_constraint_deferral.py +91 -0
- hare/models/deletion/cascade/related_rows.py +417 -0
- hare/models/deletion/cascade/tenant_schema_visits.py +96 -0
- hare/models/deletion/constants.py +29 -0
- hare/models/deletion/instance_deletion.py +288 -0
- hare/models/deletion/preview/__init__.py +1 -0
- hare/models/deletion/preview/delete_preview.py +93 -0
- hare/models/deletion/preview/delete_preview_builder.py +431 -0
- hare/models/deletion/soft_deletion.py +207 -0
- hare/models/enums.py +76 -0
- hare/models/instances/__init__.py +1 -0
- hare/models/instances/dirty_fields.py +99 -0
- hare/models/instances/field_snapshot.py +116 -0
- hare/models/instances/instance_connections.py +61 -0
- hare/models/instances/instance_copies.py +46 -0
- hare/models/instances/instance_initialization.py +323 -0
- hare/models/instances/instance_refresh.py +158 -0
- hare/models/instances/instance_saving.py +512 -0
- hare/models/meta_info.py +1143 -0
- hare/models/model.py +935 -0
- hare/models/model_meta.py +255 -0
- hare/models/tenancy/__init__.py +1 -0
- hare/models/tenancy/constants.py +16 -0
- hare/models/tenancy/tenancy.py +363 -0
- hare/models/tenancy/tenant_row_level_security.py +76 -0
- hare/models/tenancy/tenant_schemas.py +232 -0
- hare/models/uniqueness/__init__.py +0 -0
- hare/models/uniqueness/declared_uniqueness.py +99 -0
- hare/models/write/__init__.py +3 -0
- hare/models/write/generated_keys.py +97 -0
- hare/models/write/insert/__init__.py +1 -0
- hare/models/write/insert/insert_conflict.py +88 -0
- hare/models/write/insert/insert_statement.py +155 -0
- hare/models/write/instance_capture.py +173 -0
- hare/models/write/instance_values.py +126 -0
- hare/models/write/instance_writer.py +949 -0
- hare/models/write/returned_values.py +98 -0
- hare/models/write/rollback_restores.py +213 -0
- hare/models/write/rules/__init__.py +2 -0
- hare/models/write/rules/constants.py +65 -0
- hare/models/write/rules/enums.py +18 -0
- hare/models/write/rules/relation_key_values.py +50 -0
- hare/models/write/rules/row_write_rules.py +635 -0
- hare/models/write/rules/tenant_write_rules.py +300 -0
- hare/models/write/rules/written_instances.py +37 -0
- hare/models/write/rules/written_target_checks.py +63 -0
- hare/models/write/update/__init__.py +1 -0
- hare/models/write/update/expression_assignment.py +162 -0
- hare/models/write/update/update_parameter_slot.py +43 -0
- hare/models/write/write_steps.py +98 -0
- hare/native/__init__.py +1 -0
- hare/native/native_modules.py +19 -0
- hare/numbers/__init__.py +1 -0
- hare/numbers/finite_numbers.py +27 -0
- hare/py.typed +0 -0
- hare/query/__init__.py +0 -0
- hare/query/constants.py +41 -0
- hare/query/enums.py +129 -0
- hare/query/expressions/__init__.py +63 -0
- hare/query/expressions/aggregate.py +442 -0
- hare/query/expressions/aggregate_paths/__init__.py +9 -0
- hare/query/expressions/aggregate_paths/aggregate_crossing.py +20 -0
- hare/query/expressions/aggregate_paths/aggregated_multi_valued_paths.py +581 -0
- hare/query/expressions/aggregate_paths/constants.py +10 -0
- hare/query/expressions/arithmetic/__init__.py +1 -0
- hare/query/expressions/arithmetic/arithmetic_operators.py +57 -0
- hare/query/expressions/arithmetic/combinable_expression.py +47 -0
- hare/query/expressions/arithmetic/combined_expression.py +614 -0
- hare/query/expressions/arithmetic/constants.py +37 -0
- hare/query/expressions/case/__init__.py +1 -0
- hare/query/expressions/case/case.py +230 -0
- hare/query/expressions/case/case_branch_value.py +14 -0
- hare/query/expressions/case/when.py +167 -0
- hare/query/expressions/compatibility/__init__.py +9 -0
- hare/query/expressions/compatibility/constants.py +107 -0
- hare/query/expressions/compatibility/output_field_compatibility.py +248 -0
- hare/query/expressions/compatibility/result_branch.py +46 -0
- hare/query/expressions/conditions/__init__.py +1 -0
- hare/query/expressions/conditions/q.py +525 -0
- hare/query/expressions/conditions/query_modifier.py +90 -0
- hare/query/expressions/constants.py +120 -0
- hare/query/expressions/declarations.py +12 -0
- hare/query/expressions/enums.py +39 -0
- hare/query/expressions/expression.py +129 -0
- hare/query/expressions/expression_context.py +63 -0
- hare/query/expressions/expression_result.py +41 -0
- hare/query/expressions/f.py +212 -0
- hare/query/expressions/frames/__init__.py +12 -0
- hare/query/expressions/frames/constants.py +14 -0
- hare/query/expressions/frames/declarations.py +22 -0
- hare/query/expressions/frames/window_frame.py +126 -0
- hare/query/expressions/function.py +490 -0
- hare/query/expressions/joins/__init__.py +1 -0
- hare/query/expressions/joins/array_join.py +147 -0
- hare/query/expressions/joins/array_join_element.py +27 -0
- hare/query/expressions/joins/asof_join.py +263 -0
- hare/query/expressions/joins/filtered_relation.py +338 -0
- hare/query/expressions/joins/json_table.py +147 -0
- hare/query/expressions/joins/json_table_column.py +21 -0
- hare/query/expressions/joins/lateral.py +88 -0
- hare/query/expressions/joins/merge_source_row.py +44 -0
- hare/query/expressions/joins/named_columns.py +43 -0
- hare/query/expressions/joins/named_join.py +204 -0
- hare/query/expressions/numeric/__init__.py +11 -0
- hare/query/expressions/numeric/numeric_type.py +18 -0
- hare/query/expressions/numeric/numeric_typing.py +216 -0
- hare/query/expressions/numeric/unrounded_decimal_field.py +16 -0
- hare/query/expressions/ordering.py +55 -0
- hare/query/expressions/raw_sql.py +168 -0
- hare/query/expressions/subqueries/__init__.py +1 -0
- hare/query/expressions/subqueries/cte_rows.py +46 -0
- hare/query/expressions/subqueries/declarations.py +8 -0
- hare/query/expressions/subqueries/exists.py +181 -0
- hare/query/expressions/subqueries/outer_reference.py +157 -0
- hare/query/expressions/subqueries/outer_scope.py +74 -0
- hare/query/expressions/subqueries/recursive_rows.py +177 -0
- hare/query/expressions/subqueries/subquery.py +236 -0
- hare/query/expressions/temporal/__init__.py +9 -0
- hare/query/expressions/temporal/constants.py +43 -0
- hare/query/expressions/temporal/temporal_arithmetic.py +254 -0
- hare/query/expressions/temporal/temporal_operand.py +25 -0
- hare/query/expressions/term_expression.py +28 -0
- hare/query/expressions/value.py +259 -0
- hare/query/expressions/value_references/__init__.py +49 -0
- hare/query/expressions/value_references/array_value_reference.py +41 -0
- hare/query/expressions/value_references/composite_key_value_reference.py +61 -0
- hare/query/expressions/value_references/cursor_value_reference.py +41 -0
- hare/query/expressions/value_references/encoded_value_reference.py +43 -0
- hare/query/expressions/value_references/expression_arguments.py +181 -0
- hare/query/expressions/value_references/like_value_reference.py +46 -0
- hare/query/expressions/value_references/list_parameter_value_reference.py +65 -0
- hare/query/expressions/value_references/list_value_reference.py +55 -0
- hare/query/expressions/value_references/literal_value_reference.py +38 -0
- hare/query/expressions/value_references/open_range_value_reference.py +53 -0
- hare/query/expressions/value_references/range_value_reference.py +49 -0
- hare/query/expressions/value_references/rebuilt_criterion_value_reference.py +93 -0
- hare/query/expressions/value_references/related_key_value_reference.py +67 -0
- hare/query/expressions/value_references/related_value_reference.py +33 -0
- hare/query/expressions/value_references/row_list_value_reference.py +67 -0
- hare/query/expressions/value_references/scalar_value_reference.py +41 -0
- hare/query/expressions/value_references/value_reference_types.py +65 -0
- hare/query/expressions/value_references/write_value_reference.py +41 -0
- hare/query/expressions/window.py +220 -0
- hare/query/filters/__init__.py +21 -0
- hare/query/filters/constants.py +89 -0
- hare/query/filters/lookups/__init__.py +1 -0
- hare/query/filters/lookups/annotation_container_lookups.py +40 -0
- hare/query/filters/lookups/constants.py +60 -0
- hare/query/filters/lookups/containers/__init__.py +3 -0
- hare/query/filters/lookups/containers/container_field_lookups.py +78 -0
- hare/query/filters/lookups/containers/container_lookups.py +80 -0
- hare/query/filters/lookups/containers/container_value_encoders.py +94 -0
- hare/query/filters/lookups/date_part_lookups.py +292 -0
- hare/query/filters/lookups/dialect_implemented_operators.py +39 -0
- hare/query/filters/lookups/field_lookup.py +59 -0
- hare/query/filters/lookups/field_lookups.py +289 -0
- hare/query/filters/lookups/field_transforms.py +98 -0
- hare/query/filters/lookups/json/__init__.py +1 -0
- hare/query/filters/lookups/json/json_filter_guards.py +412 -0
- hare/query/filters/lookups/json/json_filter_parser.py +82 -0
- hare/query/filters/lookups/json/json_lookups.py +67 -0
- hare/query/filters/lookups/json/json_path_lookups.py +184 -0
- hare/query/filters/lookups/lookups.py +371 -0
- hare/query/filters/lookups/value_encoders.py +246 -0
- hare/query/filters/resolution/__init__.py +1 -0
- hare/query/filters/resolution/annotation_filters.py +280 -0
- hare/query/filters/resolution/composite_key_filters.py +439 -0
- hare/query/filters/resolution/filter_kwargs.py +704 -0
- hare/query/filters/resolution/filter_values.py +565 -0
- hare/query/filters/resolution/json_path_filters.py +157 -0
- hare/query/filters/resolution/lookup_support.py +84 -0
- hare/query/filters/resolution/relation_filters.py +510 -0
- hare/query/filters/resolution/sensitive_filter_keys.py +91 -0
- hare/query/filters/resolution/to_many_filters.py +436 -0
- hare/query/functions/__init__.py +185 -0
- hare/query/functions/aggregates/__init__.py +9 -0
- hare/query/functions/aggregates/array_agg.py +48 -0
- hare/query/functions/aggregates/avg.py +59 -0
- hare/query/functions/aggregates/constants.py +5 -0
- hare/query/functions/aggregates/count.py +81 -0
- hare/query/functions/aggregates/declarations.py +51 -0
- hare/query/functions/aggregates/statistic_aggregate.py +67 -0
- hare/query/functions/aggregates/sum.py +55 -0
- hare/query/functions/comparison/__init__.py +9 -0
- hare/query/functions/comparison/cast.py +121 -0
- hare/query/functions/comparison/coalesce.py +140 -0
- hare/query/functions/comparison/collate.py +45 -0
- hare/query/functions/comparison/declarations.py +21 -0
- hare/query/functions/comparison/function_arguments.py +70 -0
- hare/query/functions/comparison/greatest_least_function.py +108 -0
- hare/query/functions/comparison/null_if.py +78 -0
- hare/query/functions/containers/__init__.py +7 -0
- hare/query/functions/containers/array_item.py +69 -0
- hare/query/functions/datetime/__init__.py +55 -0
- hare/query/functions/datetime/date_function_source.py +31 -0
- hare/query/functions/datetime/declarations.py +193 -0
- hare/query/functions/datetime/extract.py +97 -0
- hare/query/functions/datetime/now.py +26 -0
- hare/query/functions/datetime/trunc.py +124 -0
- hare/query/functions/json/__init__.py +6 -0
- hare/query/functions/json/json_array.py +34 -0
- hare/query/functions/json/json_object.py +161 -0
- hare/query/functions/math/__init__.py +53 -0
- hare/query/functions/math/declarations.py +192 -0
- hare/query/functions/math/enums.py +16 -0
- hare/query/functions/math/math_function.py +110 -0
- hare/query/functions/math/mod.py +52 -0
- hare/query/functions/math/pi.py +21 -0
- hare/query/functions/math/random.py +22 -0
- hare/query/functions/math/round.py +85 -0
- hare/query/functions/text/__init__.py +55 -0
- hare/query/functions/text/concat.py +99 -0
- hare/query/functions/text/declarations.py +197 -0
- hare/query/functions/text/l_pad.py +17 -0
- hare/query/functions/text/length.py +38 -0
- hare/query/functions/text/r_pad.py +17 -0
- hare/query/functions/text/replace.py +17 -0
- hare/query/functions/text/text_function.py +114 -0
- hare/query/functions/window/__init__.py +45 -0
- hare/query/functions/window/aggregate_window_function.py +43 -0
- hare/query/functions/window/avg.py +23 -0
- hare/query/functions/window/constants.py +3 -0
- hare/query/functions/window/count.py +54 -0
- hare/query/functions/window/declarations.py +153 -0
- hare/query/functions/window/distribution_window_function.py +21 -0
- hare/query/functions/window/field_window_function.py +149 -0
- hare/query/functions/window/n_tile.py +41 -0
- hare/query/functions/window/nth_value.py +54 -0
- hare/query/functions/window/offset_window_function.py +85 -0
- hare/query/functions/window/rank_like_window_function.py +21 -0
- hare/query/functions/window/statistic_window_function.py +44 -0
- hare/query/functions/window/sum.py +23 -0
- hare/query/functions/window/window_function.py +134 -0
- hare/query/generic_foreign_keys/__init__.py +3 -0
- hare/query/generic_foreign_keys/constants.py +21 -0
- hare/query/generic_foreign_keys/generic_foreign_key_filters.py +251 -0
- hare/query/generic_foreign_keys/generic_foreign_key_paths.py +183 -0
- hare/query/generic_foreign_keys/generic_foreign_key_types.py +94 -0
- hare/query/grouping/__init__.py +14 -0
- hare/query/grouping/declarations.py +21 -0
- hare/query/grouping/grouping.py +60 -0
- hare/query/grouping/grouping_set.py +67 -0
- hare/query/grouping/grouping_sets.py +55 -0
- hare/query/key_columns.py +297 -0
- hare/query/lookup_info/__init__.py +12 -0
- hare/query/lookup_info/declarations.py +27 -0
- hare/query/lookup_info/lookup_info.py +89 -0
- hare/query/lookup_info/lookup_info_builder.py +807 -0
- hare/query/lookup_info/lookup_path.py +94 -0
- hare/query/lookup_info/lookup_paths.py +415 -0
- hare/query/lookup_info/ordering_info.py +43 -0
- hare/query/lookup_info/value_paths.py +135 -0
- hare/query/managers/__init__.py +1 -0
- hare/query/managers/base_manager.py +20 -0
- hare/query/managers/manager.py +130 -0
- hare/query/plans/__init__.py +4 -0
- hare/query/plans/call_signatures/__init__.py +1 -0
- hare/query/plans/call_signatures/call_signature_plans.py +318 -0
- hare/query/plans/call_signatures/call_signature_runs.py +466 -0
- hare/query/plans/constants.py +37 -0
- hare/query/plans/description/__init__.py +11 -0
- hare/query/plans/description/declared_plan_parts.py +7 -0
- hare/query/plans/description/filter_plan_descriptions.py +229 -0
- hare/query/plans/description/hashable_values.py +22 -0
- hare/query/plans/description/plan_context.py +33 -0
- hare/query/plans/description/plan_describer_compiler.py +355 -0
- hare/query/plans/description/plan_description.py +66 -0
- hare/query/plans/description/plan_parts.py +150 -0
- hare/query/plans/description/plannable.py +69 -0
- hare/query/plans/description/term_plan_descriptions.py +92 -0
- hare/query/plans/enums.py +97 -0
- hare/query/plans/plan_origins.py +99 -0
- hare/query/plans/recording/__init__.py +1 -0
- hare/query/plans/recording/plan_recording.py +100 -0
- hare/query/plans/recording/scope_value_source.py +67 -0
- hare/query/plans/statement/__init__.py +1 -0
- hare/query/plans/statement/declared_plan_slots.py +11 -0
- hare/query/plans/statement/query_key_compiler.py +171 -0
- hare/query/plans/statement/raw_sql_plan.py +47 -0
- hare/query/plans/statement/statement_plan.py +522 -0
- hare/query/plans/statement/statement_plan_descriptions.py +451 -0
- hare/query/plans/statement/statement_plan_runs.py +306 -0
- hare/query/plans/statement/statement_plans.py +128 -0
- hare/query/query_connection.py +110 -0
- hare/query/queryset/__init__.py +19 -0
- hare/query/queryset/annotation_access_tracker.py +20 -0
- hare/query/queryset/arguments/__init__.py +1 -0
- hare/query/queryset/arguments/annotation_arguments.py +215 -0
- hare/query/queryset/arguments/collection_arguments.py +29 -0
- hare/query/queryset/arguments/filter_arguments.py +260 -0
- hare/query/queryset/arguments/ordering_arguments.py +242 -0
- hare/query/queryset/arguments/values_arguments.py +145 -0
- hare/query/queryset/combination/__init__.py +1 -0
- hare/query/queryset/combination/combination.py +58 -0
- hare/query/queryset/combination/queryset_combination.py +109 -0
- hare/query/queryset/concrete_field_paths.py +109 -0
- hare/query/queryset/constants.py +83 -0
- hare/query/queryset/date_lists.py +74 -0
- hare/query/queryset/declarations.py +7 -0
- hare/query/queryset/extensions/__init__.py +9 -0
- hare/query/queryset/extensions/query_set_extension.py +78 -0
- hare/query/queryset/extensions/query_set_extension_call.py +19 -0
- hare/query/queryset/extensions/query_set_extension_query.py +146 -0
- hare/query/queryset/extensions/query_set_extensions.py +247 -0
- hare/query/queryset/lazy_relation_names.py +33 -0
- hare/query/queryset/model_query.py +79 -0
- hare/query/queryset/objects_by_key.py +79 -0
- hare/query/queryset/options/__init__.py +1 -0
- hare/query/queryset/options/query_option.py +42 -0
- hare/query/queryset/options/query_options.py +313 -0
- hare/query/queryset/pending_calls/__init__.py +1 -0
- hare/query/queryset/pending_calls/calls_before_setup.py +185 -0
- hare/query/queryset/pending_calls/pending_filter_calls.py +144 -0
- hare/query/queryset/query_specification.py +1088 -0
- hare/query/queryset/queryset.py +2527 -0
- hare/query/queryset/relations/__init__.py +3 -0
- hare/query/queryset/relations/linked_many_to_many_relation.py +41 -0
- hare/query/queryset/relations/many_to_many/__init__.py +1 -0
- hare/query/queryset/relations/many_to_many/linked_keys.py +147 -0
- hare/query/queryset/relations/many_to_many/linked_rows_queries.py +175 -0
- hare/query/queryset/relations/many_to_many/many_to_many_members.py +173 -0
- hare/query/queryset/relations/many_to_many/many_to_many_scope_checks.py +332 -0
- hare/query/queryset/relations/many_to_many/through_defaults.py +244 -0
- hare/query/queryset/relations/many_to_many/through_row_inserting.py +516 -0
- hare/query/queryset/relations/many_to_many/through_row_unlinking.py +333 -0
- hare/query/queryset/relations/many_to_many/through_rows.py +185 -0
- hare/query/queryset/relations/many_to_many_relation.py +382 -0
- hare/query/queryset/relations/related_queryset/__init__.py +9 -0
- hare/query/queryset/relations/related_queryset/related_query_set.py +366 -0
- hare/query/queryset/relations/related_queryset/related_rows_iterator.py +42 -0
- hare/query/queryset/relations/related_queryset/relation_rows.py +73 -0
- hare/query/queryset/relations/related_queryset/unsaved_owner_condition.py +37 -0
- hare/query/queryset/relations/reverse_relation.py +474 -0
- hare/query/queryset/row_multiplication.py +151 -0
- hare/query/queryset/schema_object_calls.py +45 -0
- hare/query/queryset/selection/__init__.py +1 -0
- hare/query/queryset/selection/statement_selection.py +217 -0
- hare/query/queryset/selection/values_selection.py +65 -0
- hare/query/queryset/single_rows/__init__.py +1 -0
- hare/query/queryset/single_rows/get_exception_argument.py +7 -0
- hare/query/queryset/single_rows/get_exceptions.py +91 -0
- hare/query/queryset/single_rows/none_awaitable_type.py +21 -0
- hare/query/queryset/single_rows/query_set_single.py +49 -0
- hare/query/queryset/single_rows/single_row.py +103 -0
- hare/query/queryset/specification_copying.py +123 -0
- hare/query/queryset/table_sample.py +60 -0
- hare/query/raw_sql/__init__.py +6 -0
- hare/query/raw_sql/execute_sql.py +71 -0
- hare/query/raw_sql/sql_query_result.py +38 -0
- hare/query/relation_loading/__init__.py +14 -0
- hare/query/relation_loading/constants.py +8 -0
- hare/query/relation_loading/prefetching/__init__.py +1 -0
- hare/query/relation_loading/prefetching/declarations.py +32 -0
- hare/query/relation_loading/prefetching/direct_relation_prefetch.py +234 -0
- hare/query/relation_loading/prefetching/many_to_many_prefetch.py +496 -0
- hare/query/relation_loading/prefetching/prefetch.py +198 -0
- hare/query/relation_loading/prefetching/prefetch_checks.py +80 -0
- hare/query/relation_loading/prefetching/prefetch_related_objects.py +48 -0
- hare/query/relation_loading/prefetching/prefetch_request.py +30 -0
- hare/query/relation_loading/prefetching/prefetcher.py +200 -0
- hare/query/relation_loading/prefetching/related_rows_fetch.py +116 -0
- hare/query/relation_loading/prefetching/reverse_relation_prefetch.py +201 -0
- hare/query/relation_loading/prefetching/sliced_prefetch.py +165 -0
- hare/query/relation_loading/select.py +26 -0
- hare/query/rows/__init__.py +3 -0
- hare/query/rows/constants.py +33 -0
- hare/query/rows/enums.py +81 -0
- hare/query/rows/model_rows/__init__.py +1 -0
- hare/query/rows/model_rows/combined_model_rows.py +254 -0
- hare/query/rows/model_rows/model_columns.py +210 -0
- hare/query/rows/model_rows/model_rows.py +462 -0
- hare/query/rows/native/__init__.py +1 -0
- hare/query/rows/native/enums.py +12 -0
- hare/query/rows/native/field_codecs.py +450 -0
- hare/query/rows/native/hydrate_accelerator.py +264 -0
- hare/query/rows/native/hydration_layout.py +114 -0
- hare/query/rows/values_rows/__init__.py +1 -0
- hare/query/rows/values_rows/combined_values_rows.py +133 -0
- hare/query/rows/values_rows/dict_rows.py +92 -0
- hare/query/rows/values_rows/flat_rows.py +33 -0
- hare/query/rows/values_rows/named_rows.py +52 -0
- hare/query/rows/values_rows/tuple_rows.py +128 -0
- hare/query/rows/values_rows/value_field.py +26 -0
- hare/query/rows/values_rows/values_rows.py +175 -0
- hare/query/scopes/__init__.py +21 -0
- hare/query/scopes/constants.py +14 -0
- hare/query/scopes/manager_scope.py +51 -0
- hare/query/scopes/row_scope.py +46 -0
- hare/query/scopes/row_scopes.py +281 -0
- hare/query/scopes/row_visibility.py +89 -0
- hare/query/scopes/scope_join_conditions.py +273 -0
- hare/query/scopes/soft_delete_scope.py +17 -0
- hare/query/scopes/tenants/__init__.py +1 -0
- hare/query/scopes/tenants/all_tenants.py +11 -0
- hare/query/scopes/tenants/model_tenants.py +79 -0
- hare/query/scopes/tenants/tenant_scope.py +70 -0
- hare/query/scopes/tenants/tenant_values.py +52 -0
- hare/query/statements/__init__.py +30 -0
- hare/query/statements/awaitable_query.py +709 -0
- hare/query/statements/building/__init__.py +1 -0
- hare/query/statements/building/keyset_bounds.py +179 -0
- hare/query/statements/building/query_annotations.py +350 -0
- hare/query/statements/building/query_conditions.py +244 -0
- hare/query/statements/building/query_ctes.py +70 -0
- hare/query/statements/building/query_grouping.py +347 -0
- hare/query/statements/building/query_joins.py +282 -0
- hare/query/statements/building/query_ordering.py +275 -0
- hare/query/statements/building/row_locks.py +216 -0
- hare/query/statements/constants.py +111 -0
- hare/query/statements/select/__init__.py +4 -0
- hare/query/statements/select/combined/__init__.py +1 -0
- hare/query/statements/select/combined/combined_branches.py +380 -0
- hare/query/statements/select/combined/combined_derived_queries.py +220 -0
- hare/query/statements/select/combined/combined_plan_descriptions.py +43 -0
- hare/query/statements/select/combined_query.py +354 -0
- hare/query/statements/select/model_rows/__init__.py +1 -0
- hare/query/statements/select/model_rows/instance_hydration.py +162 -0
- hare/query/statements/select/model_rows/model_rows_plan_descriptions.py +108 -0
- hare/query/statements/select/model_rows/only_defer_fields.py +243 -0
- hare/query/statements/select/model_rows/select_related_joins.py +112 -0
- hare/query/statements/select/model_rows_query.py +416 -0
- hare/query/statements/select/raw_sql_query.py +151 -0
- hare/query/statements/select/rows_query.py +210 -0
- hare/query/statements/select/select_query.py +110 -0
- hare/query/statements/select/values/__init__.py +1 -0
- hare/query/statements/select/values/constants.py +9 -0
- hare/query/statements/select/values/values_distinct.py +41 -0
- hare/query/statements/select/values/values_grouping.py +118 -0
- hare/query/statements/select/values/values_output.py +298 -0
- hare/query/statements/select/values/values_reading.py +26 -0
- hare/query/statements/select/values/window_filter_wrapping.py +91 -0
- hare/query/statements/select/values_query.py +754 -0
- hare/query/statements/summary/__init__.py +3 -0
- hare/query/statements/summary/aggregate_query.py +732 -0
- hare/query/statements/summary/contains_query.py +66 -0
- hare/query/statements/summary/count_query.py +117 -0
- hare/query/statements/summary/exists_query.py +151 -0
- hare/query/statements/summary/rows_summary_query.py +187 -0
- hare/query/statements/write/__init__.py +3 -0
- hare/query/statements/write/bulk/__init__.py +1 -0
- hare/query/statements/write/bulk/bulk_objects.py +61 -0
- hare/query/statements/write/bulk/bulk_update_checks.py +92 -0
- hare/query/statements/write/bulk/bulk_update_query.py +1012 -0
- hare/query/statements/write/bulk/bulk_write_batches.py +368 -0
- hare/query/statements/write/bulk/create/__init__.py +1 -0
- hare/query/statements/write/bulk/create/bulk_create_query.py +936 -0
- hare/query/statements/write/bulk/create/bulk_create_reports.py +316 -0
- hare/query/statements/write/bulk/create/conflict_clause.py +137 -0
- hare/query/statements/write/bulk/create/copy_insert.py +143 -0
- hare/query/statements/write/bulk/create/default_rows_insert.py +85 -0
- hare/query/statements/write/bulk/create/inline_insert.py +93 -0
- hare/query/statements/write/bulk/create/multi_row_insert.py +277 -0
- hare/query/statements/write/bulk/create/returned_rows_matching.py +136 -0
- hare/query/statements/write/bulk/create/template_insert.py +185 -0
- hare/query/statements/write/bulk/declarations.py +61 -0
- hare/query/statements/write/create_or_update.py +193 -0
- hare/query/statements/write/declarations.py +26 -0
- hare/query/statements/write/delete_query.py +402 -0
- hare/query/statements/write/insert_from_query.py +373 -0
- hare/query/statements/write/matching_rows_query.py +268 -0
- hare/query/statements/write/merge/__init__.py +1 -0
- hare/query/statements/write/merge/merge_query.py +818 -0
- hare/query/statements/write/merge/merge_when.py +87 -0
- hare/query/statements/write/restore_query.py +105 -0
- hare/query/statements/write/returning/__init__.py +1 -0
- hare/query/statements/write/returning/delete_returning_query.py +154 -0
- hare/query/statements/write/returning/returned_rows.py +246 -0
- hare/query/statements/write/returning/update_returning_query.py +120 -0
- hare/query/statements/write/update_query.py +851 -0
- hare/search/__init__.py +29 -0
- hare/search/constants.py +22 -0
- hare/search/enums.py +26 -0
- hare/search/query/__init__.py +8 -0
- hare/search/query/combined_search_query.py +46 -0
- hare/search/query/declarations.py +9 -0
- hare/search/query/search_query.py +75 -0
- hare/search/query/search_query_combinable.py +40 -0
- hare/search/search_arguments.py +79 -0
- hare/search/search_features.py +35 -0
- hare/search/search_headline.py +186 -0
- hare/search/search_rank.py +144 -0
- hare/search/types.py +16 -0
- hare/search/vector/__init__.py +7 -0
- hare/search/vector/combined_search_vector.py +32 -0
- hare/search/vector/search_vector.py +77 -0
- hare/search/vector/search_vector_combinable.py +30 -0
- hare/sql/__init__.py +71 -0
- hare/sql/analytics/__init__.py +17 -0
- hare/sql/analytics/count.py +13 -0
- hare/sql/analytics/current_row.py +10 -0
- hare/sql/analytics/declarations.py +15 -0
- hare/sql/analytics/row_number.py +13 -0
- hare/sql/builder/__init__.py +29 -0
- hare/sql/builder/joins/__init__.py +16 -0
- hare/sql/builder/joins/join.py +71 -0
- hare/sql/builder/joins/join_on.py +73 -0
- hare/sql/builder/joins/joiner.py +38 -0
- hare/sql/builder/queries/__init__.py +17 -0
- hare/sql/builder/queries/constants.py +5 -0
- hare/sql/builder/queries/correlated_subqueries.py +583 -0
- hare/sql/builder/queries/pagination_sql.py +19 -0
- hare/sql/builder/queries/query.py +109 -0
- hare/sql/builder/queries/query_builder.py +1090 -0
- hare/sql/builder/queries/query_sql_rendering.py +407 -0
- hare/sql/builder/queries/set_operation_query.py +203 -0
- hare/sql/builder/returned_value.py +19 -0
- hare/sql/builder/tables/__init__.py +22 -0
- hare/sql/builder/tables/aliased_query.py +33 -0
- hare/sql/builder/tables/array_join_source.py +39 -0
- hare/sql/builder/tables/asof_join_source.py +29 -0
- hare/sql/builder/tables/cte.py +18 -0
- hare/sql/builder/tables/database.py +12 -0
- hare/sql/builder/tables/json_table_query.py +76 -0
- hare/sql/builder/tables/lateral_query.py +26 -0
- hare/sql/builder/tables/schema.py +42 -0
- hare/sql/builder/tables/selectable.py +83 -0
- hare/sql/builder/tables/table.py +170 -0
- hare/sql/builder_methods.py +56 -0
- hare/sql/constants.py +87 -0
- hare/sql/enums.py +211 -0
- hare/sql/exceptions.py +31 -0
- hare/sql/functions/__init__.py +81 -0
- hare/sql/functions/address_text.py +18 -0
- hare/sql/functions/cast.py +19 -0
- hare/sql/functions/cast_to.py +38 -0
- hare/sql/functions/coalesce.py +13 -0
- hare/sql/functions/count.py +14 -0
- hare/sql/functions/datetime/__init__.py +1 -0
- hare/sql/functions/datetime/date.py +16 -0
- hare/sql/functions/datetime/date_as_timestamp.py +23 -0
- hare/sql/functions/datetime/date_trunc.py +65 -0
- hare/sql/functions/datetime/datetime_as_text.py +16 -0
- hare/sql/functions/datetime/datetime_cast.py +68 -0
- hare/sql/functions/datetime/extract.py +92 -0
- hare/sql/functions/datetime/now.py +14 -0
- hare/sql/functions/datetime/temporal_difference.py +26 -0
- hare/sql/functions/datetime/temporal_shift.py +38 -0
- hare/sql/functions/datetime/timestamp_comparand.py +18 -0
- hare/sql/functions/declarations.py +19 -0
- hare/sql/functions/distinct_option_function.py +33 -0
- hare/sql/functions/greatest_least.py +25 -0
- hare/sql/functions/grouping_function.py +13 -0
- hare/sql/functions/json/__init__.py +1 -0
- hare/sql/functions/json/json_array.py +14 -0
- hare/sql/functions/json/json_object.py +14 -0
- hare/sql/functions/json/json_sort_key.py +15 -0
- hare/sql/functions/json/json_value.py +19 -0
- hare/sql/functions/numeric_cast.py +16 -0
- hare/sql/functions/random_number.py +13 -0
- hare/sql/functions/round.py +20 -0
- hare/sql/functions/statistic.py +20 -0
- hare/sql/functions/std_dev.py +13 -0
- hare/sql/functions/text/__init__.py +1 -0
- hare/sql/functions/text/collate.py +61 -0
- hare/sql/functions/text/concat.py +18 -0
- hare/sql/functions/text/concat_function.py +53 -0
- hare/sql/functions/text/decimal_text_collate.py +16 -0
- hare/sql/functions/text/lower.py +12 -0
- hare/sql/functions/text/replace.py +12 -0
- hare/sql/functions/text/upper.py +12 -0
- hare/sql/identifiers.py +61 -0
- hare/sql/sql_context.py +155 -0
- hare/sql/terms/__init__.py +90 -0
- hare/sql/terms/arithmetic_expression.py +120 -0
- hare/sql/terms/array.py +109 -0
- hare/sql/terms/bracket.py +12 -0
- hare/sql/terms/case/__init__.py +1 -0
- hare/sql/terms/case/case.py +123 -0
- hare/sql/terms/case/when_then.py +11 -0
- hare/sql/terms/constants.py +5 -0
- hare/sql/terms/containers/__init__.py +35 -0
- hare/sql/terms/containers/array_element_term.py +58 -0
- hare/sql/terms/containers/array_slice_term.py +28 -0
- hare/sql/terms/containers/constants.py +6 -0
- hare/sql/terms/containers/container_function.py +22 -0
- hare/sql/terms/containers/container_literal.py +37 -0
- hare/sql/terms/containers/declarations.py +47 -0
- hare/sql/terms/containers/map_value_term.py +30 -0
- hare/sql/terms/containers/tuple_element_term.py +21 -0
- hare/sql/terms/criteria/__init__.py +37 -0
- hare/sql/terms/criteria/basic_criterion.py +92 -0
- hare/sql/terms/criteria/between_criterion.py +39 -0
- hare/sql/terms/criteria/complex_criterion.py +47 -0
- hare/sql/terms/criteria/contains_criterion.py +81 -0
- hare/sql/terms/criteria/criterion.py +87 -0
- hare/sql/terms/criteria/empty_criterion.py +38 -0
- hare/sql/terms/criteria/is_distinct_from_criterion.py +52 -0
- hare/sql/terms/criteria/is_not_true_criterion.py +49 -0
- hare/sql/terms/criteria/json_attribute_criterion.py +62 -0
- hare/sql/terms/criteria/like.py +56 -0
- hare/sql/terms/criteria/nested_criterion.py +78 -0
- hare/sql/terms/criteria/not_criterion.py +78 -0
- hare/sql/terms/criteria/null_criterion.py +47 -0
- hare/sql/terms/criteria/range_criterion.py +28 -0
- hare/sql/terms/criteria/true_criterion.py +13 -0
- hare/sql/terms/field.py +65 -0
- hare/sql/terms/functions/__init__.py +30 -0
- hare/sql/terms/functions/aggregate_function.py +119 -0
- hare/sql/terms/functions/analytic_function.py +107 -0
- hare/sql/terms/functions/custom_function.py +39 -0
- hare/sql/terms/functions/decimal_mod.py +27 -0
- hare/sql/terms/functions/float_mod.py +24 -0
- hare/sql/terms/functions/function.py +131 -0
- hare/sql/terms/functions/interval.py +110 -0
- hare/sql/terms/functions/mod.py +22 -0
- hare/sql/terms/functions/pow.py +11 -0
- hare/sql/terms/functions/window_frame_analytic_function.py +78 -0
- hare/sql/terms/grouping/__init__.py +14 -0
- hare/sql/terms/grouping/declarations.py +17 -0
- hare/sql/terms/grouping/grouping_element.py +42 -0
- hare/sql/terms/grouping/grouping_sets_element.py +46 -0
- hare/sql/terms/index.py +15 -0
- hare/sql/terms/infix_operator.py +34 -0
- hare/sql/terms/json.py +100 -0
- hare/sql/terms/negative.py +49 -0
- hare/sql/terms/node.py +135 -0
- hare/sql/terms/parameters/__init__.py +1 -0
- hare/sql/terms/parameters/list_parameter.py +33 -0
- hare/sql/terms/parameters/parameter.py +35 -0
- hare/sql/terms/parameters/parameterized_value_wrapper.py +19 -0
- hare/sql/terms/parameters/parameterizer.py +99 -0
- hare/sql/terms/parameters/query_parameters.py +74 -0
- hare/sql/terms/parameters/recording_parameterizer.py +27 -0
- hare/sql/terms/qualified_outer_field.py +58 -0
- hare/sql/terms/select_reference.py +80 -0
- hare/sql/terms/star.py +30 -0
- hare/sql/terms/subqueries/__init__.py +1 -0
- hare/sql/terms/subqueries/exists_term.py +111 -0
- hare/sql/terms/subqueries/outer_aggregate_term.py +51 -0
- hare/sql/terms/term.py +334 -0
- hare/sql/terms/term_identity_text.py +60 -0
- hare/sql/terms/tuple.py +52 -0
- hare/sql/terms/values/__init__.py +1 -0
- hare/sql/terms/values/literal_value.py +21 -0
- hare/sql/terms/values/null_value.py +10 -0
- hare/sql/terms/values/old_row_value.py +28 -0
- hare/sql/terms/values/row_value_list.py +15 -0
- hare/sql/terms/values/value_wrapper.py +129 -0
- hare/sql/types/__init__.py +1 -0
- hare/sql/types/sql_type.py +13 -0
- hare/sql/types/sql_types.py +17 -0
- hare/stubs/__init__.py +2 -0
- hare/stubs/constants.py +18 -0
- hare/stubs/model_stub.py +415 -0
- hare/stubs/module_stub.py +150 -0
- hare/stubs/stub_imports.py +91 -0
- hare/stubs/stub_writer.py +60 -0
- hare/stubs/value_type_text.py +98 -0
- hare/time/__init__.py +12 -0
- hare/time/constants.py +27 -0
- hare/time/system_clock.py +84 -0
- hare/time/timezone.py +534 -0
- hare/time/zone_info.py +13 -0
- hare/transactions/__init__.py +25 -0
- hare/transactions/atomic/__init__.py +1 -0
- hare/transactions/atomic/atomic.py +138 -0
- hare/transactions/atomic/atomic_attempt.py +62 -0
- hare/transactions/atomic/atomic_attempts.py +73 -0
- hare/transactions/constants.py +41 -0
- hare/transactions/distributed/__init__.py +9 -0
- hare/transactions/distributed/declarations.py +32 -0
- hare/transactions/distributed/distributed_coordinator.py +784 -0
- hare/transactions/distributed/distributed_transactions.py +26 -0
- hare/transactions/distributed/stale_prepared_transaction.py +23 -0
- hare/transactions/enums.py +31 -0
- hare/transactions/transaction_options.py +86 -0
- hare/transactions/transactions.py +228 -0
- hare/typing_info/__init__.py +3 -0
- hare/typing_info/bound_models.py +73 -0
- hare/typing_info/constants.py +13 -0
- hare/typing_info/declarations.py +44 -0
- hare/typing_info/filter_value_types.py +144 -0
- hare/vectors/__init__.py +18 -0
- hare/vectors/constants.py +10 -0
- hare/vectors/declarations.py +41 -0
- hare/vectors/enums.py +14 -0
- hare/vectors/terms/__init__.py +6 -0
- hare/vectors/terms/vector_distance_term.py +22 -0
- hare/vectors/terms/vector_literal.py +18 -0
- hare/vectors/vector_distance_expression.py +107 -0
- hare/vectors/vector_field.py +147 -0
- hare/warnings.py +13 -0
- hare_orm-0.9.0.dist-info/LICENSE +27 -0
- hare_orm-0.9.0.dist-info/METADATA +321 -0
- hare_orm-0.9.0.dist-info/NOTICE.md +96 -0
- hare_orm-0.9.0.dist-info/NOTICE.ru.md +98 -0
- hare_orm-0.9.0.dist-info/RECORD +2267 -0
- hare_orm-0.9.0.dist-info/WHEEL +4 -0
- hare_orm-0.9.0.dist-info/entry_points.txt +6 -0
|
@@ -0,0 +1,1259 @@
|
|
|
1
|
+
"""``RequestQuery`` - the rows a request asks for, declared once: the queryset, the parameters it
|
|
2
|
+
filters by, the search, the orderings a request may choose and the pagination."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import asyncio
|
|
7
|
+
import dataclasses
|
|
8
|
+
import inspect
|
|
9
|
+
import json
|
|
10
|
+
from collections.abc import Callable, Iterable, Iterator
|
|
11
|
+
from contextlib import contextmanager
|
|
12
|
+
from functools import partial
|
|
13
|
+
from typing import TYPE_CHECKING, Any, ClassVar, Self, cast, overload
|
|
14
|
+
from urllib.parse import parse_qsl
|
|
15
|
+
from weakref import WeakKeyDictionary, WeakSet, ref
|
|
16
|
+
|
|
17
|
+
from pydantic import BaseModel, ConfigDict, PrivateAttr, ValidationError
|
|
18
|
+
from pydantic.fields import FieldInfo
|
|
19
|
+
|
|
20
|
+
from hare.contrib.request_query.constants import (
|
|
21
|
+
DECLARATION_BUCKET_KEY,
|
|
22
|
+
DESCENDING_PREFIX,
|
|
23
|
+
INVALID_VALUE_ERROR_TYPE,
|
|
24
|
+
MANY_VALUE_PARAMETERS_BUCKET_KEY,
|
|
25
|
+
META_CLASS_NAME,
|
|
26
|
+
MISSING_FILTER_ERROR_TYPE,
|
|
27
|
+
PARAMETER_OPTION_NAMES,
|
|
28
|
+
REQUEST_OPTIONS_BUCKET_KEY,
|
|
29
|
+
)
|
|
30
|
+
from hare.contrib.request_query.declaration.declaration_builder import DeclarationBuilder
|
|
31
|
+
from hare.contrib.request_query.declaration.filter_declaration import FilterDeclaration
|
|
32
|
+
from hare.contrib.request_query.declaration.filter_parameter_builder import FilterParameterBuilder
|
|
33
|
+
from hare.contrib.request_query.declaration.request_query_declaration import RequestQueryDeclaration
|
|
34
|
+
from hare.contrib.request_query.declaration.request_query_parameters import RequestQueryParameters
|
|
35
|
+
from hare.contrib.request_query.declaration.request_query_registry import RequestQueryRegistry
|
|
36
|
+
from hare.contrib.request_query.descriptions.parameter_describer import ParameterDescriber
|
|
37
|
+
from hare.contrib.request_query.descriptions.parameter_description import ParameterDescription
|
|
38
|
+
from hare.contrib.request_query.enums import DeletedRows, EachRowOnce
|
|
39
|
+
from hare.contrib.request_query.exceptions import InvalidRequestQuery, RequestQueryForbidden
|
|
40
|
+
from hare.contrib.request_query.options.deleted_config import DeletedConfig
|
|
41
|
+
from hare.contrib.request_query.options.fields_config import FieldsConfig
|
|
42
|
+
from hare.contrib.request_query.options.filter_field import FilterField
|
|
43
|
+
from hare.contrib.request_query.options.include_config import IncludeConfig
|
|
44
|
+
from hare.contrib.request_query.options.latest_versions import LatestVersions
|
|
45
|
+
from hare.contrib.request_query.options.ordering_config import OrderingConfig
|
|
46
|
+
from hare.contrib.request_query.options.request_option import RequestOption
|
|
47
|
+
from hare.contrib.request_query.options.search_config import SearchConfig
|
|
48
|
+
from hare.contrib.request_query.paginations.offset_pagination import OffsetPagination
|
|
49
|
+
from hare.contrib.request_query.paginations.pagination import Pagination
|
|
50
|
+
from hare.contrib.request_query.row_changes import RowChanges
|
|
51
|
+
from hare.contrib.request_query.value_annotation import ValueAnnotation
|
|
52
|
+
from hare.contrib.request_query.value_counter import ValueCounter
|
|
53
|
+
from hare.contrib.request_query.value_target import ValueTarget
|
|
54
|
+
from hare.core.caching.cache import Cache
|
|
55
|
+
from hare.core.caching.caches import Caches
|
|
56
|
+
from hare.core.hare_context import HareContext
|
|
57
|
+
from hare.exceptions import ConfigurationError, QueryError, ValidationError as FieldValidationError
|
|
58
|
+
from hare.models import Model
|
|
59
|
+
from hare.query.enums import Connector, GetException
|
|
60
|
+
from hare.query.expressions import Q
|
|
61
|
+
from hare.query.expressions.ordering import Ordering
|
|
62
|
+
from hare.query.queryset import QuerySet
|
|
63
|
+
from hare.query.queryset.selection.statement_selection import StatementSelection
|
|
64
|
+
|
|
65
|
+
if TYPE_CHECKING:
|
|
66
|
+
from hare.contrib.request_query.results.cursor_page import CursorPage
|
|
67
|
+
from hare.contrib.request_query.results.page import Page
|
|
68
|
+
from hare.contrib.request_query.results.scroll_page import ScrollPage
|
|
69
|
+
from hare.dialects.base.dialect import Dialect
|
|
70
|
+
from hare.query.lookup_info.ordering_info import OrderingInfo
|
|
71
|
+
from hare.query.queryset.single_rows.get_exception_argument import GetExceptionArgument
|
|
72
|
+
|
|
73
|
+
#: One item of an ordering: a name with ``-`` for descending, or an ordering expression.
|
|
74
|
+
type OrderingItem = str | Ordering
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class RequestQuery[ModelType: Model](BaseModel):
|
|
78
|
+
"""The rows a request asks for.
|
|
79
|
+
|
|
80
|
+
A subclass declares the queryset it starts from, its parameters - each a filter the ORM
|
|
81
|
+
describes, checked when the application starts - and its search, ordering and pagination::
|
|
82
|
+
|
|
83
|
+
class BookQuery(RequestQuery[Book]):
|
|
84
|
+
author: int | None = None
|
|
85
|
+
title__icontains: str | None = None
|
|
86
|
+
genre_ids: Annotated[list[int] | None, Filter("genres", lookup="in")] = None
|
|
87
|
+
|
|
88
|
+
class Meta:
|
|
89
|
+
queryset = Book.objects.all().select_related("author")
|
|
90
|
+
search = SearchConfig(fields=("title", "author__name"))
|
|
91
|
+
ordering = OrderingConfig(fields=("title", "published_at"), default=("-published_at",))
|
|
92
|
+
pagination = OffsetPagination(default_limit=50)
|
|
93
|
+
|
|
94
|
+
A framework adapter builds an instance from the request's parameters; ``page()``, ``fetch()``,
|
|
95
|
+
``get()``, ``count()``, ``exists()`` and ``delete()`` run it.
|
|
96
|
+
|
|
97
|
+
``RequestQuery`` checks its filters against every dialect a driver connects to; a subclass
|
|
98
|
+
of one dialect (``dialect``) - each of hare's dialects has one in its package - checks
|
|
99
|
+
against that dialect only, and may use the lookups only it runs.
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
model_config = ConfigDict(extra="forbid", arbitrary_types_allowed=True)
|
|
103
|
+
|
|
104
|
+
#: The dialect the class's filters are checked against, None for every dialect.
|
|
105
|
+
dialect: ClassVar[Dialect | None] = None
|
|
106
|
+
|
|
107
|
+
#: The buckets of the caches the class reads (``Cache.get_owner_bucket()``) - a dict of its
|
|
108
|
+
#: own for every request query class.
|
|
109
|
+
cache_buckets: ClassVar[dict[int, Any]] = {}
|
|
110
|
+
|
|
111
|
+
#: The checked declaration of each request query class, its options that add parameters and
|
|
112
|
+
#: the parameters taking every value of a repeated query parameter, in a bucket the class
|
|
113
|
+
#: keeps - so a class nothing else holds (one a test declares) is gone with it.
|
|
114
|
+
declarations: ClassVar[Cache[Any]] = Cache(holds_sql=False, keyed_by_model=False)
|
|
115
|
+
|
|
116
|
+
#: The request query classes ``prepare_parameters()`` completed - weakly, as ``declarations``.
|
|
117
|
+
prepared_classes: ClassVar[WeakSet[type]] = WeakSet()
|
|
118
|
+
|
|
119
|
+
#: The parameters of each prepared class as they were before ``prepare_parameters()`` added
|
|
120
|
+
#: ``Meta.filters``' and described the filters - put back when the class is forgotten.
|
|
121
|
+
unprepared_fields: ClassVar[WeakKeyDictionary[type, dict[str, FieldInfo]]] = WeakKeyDictionary()
|
|
122
|
+
|
|
123
|
+
#: The request query classes whose parameters or declaration read each model - both weakly.
|
|
124
|
+
#: A change to the model (``Caches.forget_model_caches()``: a live model unregistered or
|
|
125
|
+
#: registered again, a relation added, any registration in ``Registries``) forgets them.
|
|
126
|
+
classes_by_model: ClassVar[WeakKeyDictionary[type[Model], WeakSet[type]]] = WeakKeyDictionary()
|
|
127
|
+
|
|
128
|
+
#: Every model a request query was prepared for while it was bound - one that is no longer
|
|
129
|
+
#: bound was unregistered, not merely not bound yet.
|
|
130
|
+
bound_models: ClassVar[WeakSet[type[Model]]] = WeakSet()
|
|
131
|
+
|
|
132
|
+
class Meta:
|
|
133
|
+
"""The options of a request query.
|
|
134
|
+
|
|
135
|
+
Attributes:
|
|
136
|
+
queryset: The rows the query starts from. A class without one only serves as a base.
|
|
137
|
+
search: A ``SearchConfig``, None without a search.
|
|
138
|
+
ordering: An ``OrderingConfig``, None when a request can't choose the ordering.
|
|
139
|
+
pagination: An ``OffsetPagination``, a ``ScrollPagination`` or a ``CursorPagination``,
|
|
140
|
+
None without pagination.
|
|
141
|
+
filters: A tuple of ``FilterField`` - the fields a request may filter by and each
|
|
142
|
+
one's lookups: ``FilterField("status", lookups=(Lookup.EXACT, Lookup.IN))`` makes
|
|
143
|
+
the parameters ``status`` and ``status__in``, typed by the ORM. None for only the
|
|
144
|
+
parameters the class declares.
|
|
145
|
+
join_type: How the conditions of the parameters join - ``Connector.AND`` or ``Connector.OR``.
|
|
146
|
+
fields: A ``FieldsConfig``, None when a request can't choose the fields to load.
|
|
147
|
+
include: An ``IncludeConfig``, None when a request can't ask for relations.
|
|
148
|
+
deleted: A ``DeletedConfig``, None when a request can't see soft-deleted rows.
|
|
149
|
+
versions: ``LatestVersions()`` to keep only the latest version of each record of a
|
|
150
|
+
``VersionedModel``, None for every version.
|
|
151
|
+
"""
|
|
152
|
+
|
|
153
|
+
queryset: QuerySet[Any] | None = None
|
|
154
|
+
filters: tuple[FilterField, ...] | None = None
|
|
155
|
+
search: SearchConfig | None = None
|
|
156
|
+
ordering: OrderingConfig | None = None
|
|
157
|
+
pagination: Pagination | None = OffsetPagination()
|
|
158
|
+
join_type: Connector = Connector.AND
|
|
159
|
+
fields: FieldsConfig | None = None
|
|
160
|
+
include: IncludeConfig | None = None
|
|
161
|
+
deleted: DeletedConfig | None = None
|
|
162
|
+
versions: LatestVersions | None = None
|
|
163
|
+
|
|
164
|
+
_request: Any = PrivateAttr(default=None)
|
|
165
|
+
_request_url: str | None = PrivateAttr(default=None)
|
|
166
|
+
# Tuples, not lists with a default_factory - pydantic reads a factory's signature on every
|
|
167
|
+
# instance it makes.
|
|
168
|
+
_conditions: tuple[Q, ...] = PrivateAttr(default=())
|
|
169
|
+
_explicit_ordering: tuple[OrderingItem, ...] | None = PrivateAttr(default=None)
|
|
170
|
+
_queryset_changes: tuple[Callable[[QuerySet[Any]], QuerySet[Any]], ...] = PrivateAttr(default=())
|
|
171
|
+
|
|
172
|
+
def __init__(self, request: Any = None, **values: Any) -> None:
|
|
173
|
+
"""Reads the parameters of a request.
|
|
174
|
+
|
|
175
|
+
Args:
|
|
176
|
+
request: The request the parameters come from - its ``url`` makes the links of a page.
|
|
177
|
+
values: The parameters.
|
|
178
|
+
|
|
179
|
+
Raises:
|
|
180
|
+
InvalidRequestQuery: A value has the wrong type or is out of range, an option's
|
|
181
|
+
parameter names what the option doesn't allow, or a field's bounds leave no value
|
|
182
|
+
between them (``published_at__gte`` after ``published_at__lte``).
|
|
183
|
+
"""
|
|
184
|
+
type(self).prepare_parameters()
|
|
185
|
+
try:
|
|
186
|
+
super().__init__(**values)
|
|
187
|
+
except ValidationError as error:
|
|
188
|
+
raise InvalidRequestQuery(
|
|
189
|
+
[
|
|
190
|
+
{"loc": list(item["loc"]), "msg": item["msg"], "type": item["type"]}
|
|
191
|
+
for item in error.errors(include_url=False)
|
|
192
|
+
]
|
|
193
|
+
) from error
|
|
194
|
+
self._request = request
|
|
195
|
+
parameter_values = RequestQueryParameters.get_parameter_values(self)
|
|
196
|
+
for option in self.get_request_options():
|
|
197
|
+
option.check_request(parameter_values)
|
|
198
|
+
for bounds in self.get_declaration().bounds:
|
|
199
|
+
bounds.check(parameter_values)
|
|
200
|
+
|
|
201
|
+
@classmethod
|
|
202
|
+
def from_query_string(cls, query_string: str, *, request: Any = None, **values: Any) -> Self:
|
|
203
|
+
"""Builds the query from a URL's query string, without a web framework - for tests, a CLI,
|
|
204
|
+
a WebSocket message or a framework without an adapter.
|
|
205
|
+
|
|
206
|
+
Args:
|
|
207
|
+
query_string: The query string, without ``?`` (``status=draft&tag=1&tag=2``).
|
|
208
|
+
request: The request, if any - its ``url`` makes the links of a page.
|
|
209
|
+
values: Values of other parameters (path parameters) - they win over the query string.
|
|
210
|
+
|
|
211
|
+
Returns:
|
|
212
|
+
The query.
|
|
213
|
+
|
|
214
|
+
Raises:
|
|
215
|
+
InvalidRequestQuery: See ``__init__()``.
|
|
216
|
+
"""
|
|
217
|
+
return cls.from_query_parameters(parse_qsl(query_string, keep_blank_values=True), request=request, **values)
|
|
218
|
+
|
|
219
|
+
@classmethod
|
|
220
|
+
def from_query_parameters(
|
|
221
|
+
cls, parameters: Iterable[tuple[str, str]], *, request: Any = None, **values: Any
|
|
222
|
+
) -> Self:
|
|
223
|
+
"""Builds the query from query parameters as pairs, a name repeated for each of its values.
|
|
224
|
+
A parameter taking a list gets every value, any other the last one; a name the query
|
|
225
|
+
doesn't have is ignored, as a web framework ignores it.
|
|
226
|
+
|
|
227
|
+
Args:
|
|
228
|
+
parameters: ``(name, value)`` pairs.
|
|
229
|
+
request: The request, if any.
|
|
230
|
+
values: Values of other parameters - they win over ``parameters``.
|
|
231
|
+
|
|
232
|
+
Returns:
|
|
233
|
+
The query.
|
|
234
|
+
|
|
235
|
+
Raises:
|
|
236
|
+
InvalidRequestQuery: See ``__init__()``.
|
|
237
|
+
"""
|
|
238
|
+
cls.prepare_parameters()
|
|
239
|
+
collected: dict[str, list[str]] = {}
|
|
240
|
+
for name, value in parameters:
|
|
241
|
+
collected.setdefault(name, []).append(value)
|
|
242
|
+
many_value_names = cls.get_many_value_parameter_names()
|
|
243
|
+
arguments: dict[str, Any] = {}
|
|
244
|
+
for name in cls.model_fields:
|
|
245
|
+
if name in collected:
|
|
246
|
+
arguments[name] = collected[name] if name in many_value_names else collected[name][-1]
|
|
247
|
+
arguments.update(values)
|
|
248
|
+
return cls(request=request, **arguments)
|
|
249
|
+
|
|
250
|
+
@classmethod
|
|
251
|
+
def get_many_value_parameter_names(cls) -> frozenset[str]:
|
|
252
|
+
"""The parameters taking every value of a repeated query parameter, not one - worked out
|
|
253
|
+
once the class's parameters are prepared.
|
|
254
|
+
|
|
255
|
+
Returns:
|
|
256
|
+
Their names.
|
|
257
|
+
"""
|
|
258
|
+
bucket = cls.get_cache_bucket()
|
|
259
|
+
names: frozenset[str] | None = bucket.get(MANY_VALUE_PARAMETERS_BUCKET_KEY)
|
|
260
|
+
if names is None:
|
|
261
|
+
names = frozenset(
|
|
262
|
+
name
|
|
263
|
+
for name, field_info in cls.model_fields.items()
|
|
264
|
+
if ValueAnnotation.takes_many_values(field_info.annotation, field_info.metadata)
|
|
265
|
+
)
|
|
266
|
+
# The parameters of a class not prepared yet still change.
|
|
267
|
+
if cls in RequestQuery.prepared_classes:
|
|
268
|
+
bucket[MANY_VALUE_PARAMETERS_BUCKET_KEY] = names
|
|
269
|
+
return names
|
|
270
|
+
|
|
271
|
+
@classmethod
|
|
272
|
+
def get_cache_bucket(cls) -> dict[Any, Any]:
|
|
273
|
+
"""The bucket of ``declarations`` the class keeps - read off the class's own buckets, which
|
|
274
|
+
costs less than asking the cache.
|
|
275
|
+
|
|
276
|
+
Returns:
|
|
277
|
+
The bucket.
|
|
278
|
+
"""
|
|
279
|
+
bucket = cls.cache_buckets.get(RequestQuery.declarations.bucket_id)
|
|
280
|
+
return bucket if bucket is not None else RequestQuery.declarations.get_owner_bucket(cls)
|
|
281
|
+
|
|
282
|
+
@classmethod
|
|
283
|
+
def get_meta_option(cls, name: str) -> Any:
|
|
284
|
+
"""One ``Meta`` option of the class: from its own ``Meta``, else the nearest base's.
|
|
285
|
+
|
|
286
|
+
Args:
|
|
287
|
+
name: The option.
|
|
288
|
+
|
|
289
|
+
Returns:
|
|
290
|
+
The option.
|
|
291
|
+
"""
|
|
292
|
+
for klass in cls.__mro__:
|
|
293
|
+
meta = vars(klass).get(META_CLASS_NAME)
|
|
294
|
+
if meta is not None and name in vars(meta):
|
|
295
|
+
return vars(meta)[name]
|
|
296
|
+
return None
|
|
297
|
+
|
|
298
|
+
@classmethod
|
|
299
|
+
def __pydantic_init_subclass__(cls, **kwargs: Any) -> None:
|
|
300
|
+
"""Adds the parameters the class's options bring - the search, the ordering, the
|
|
301
|
+
pagination parameters and the others - once pydantic built the class. A parameter the
|
|
302
|
+
class declares itself is kept as declared.
|
|
303
|
+
|
|
304
|
+
Args:
|
|
305
|
+
kwargs: The class's keyword arguments.
|
|
306
|
+
"""
|
|
307
|
+
super().__pydantic_init_subclass__(**kwargs)
|
|
308
|
+
cls.cache_buckets = {}
|
|
309
|
+
RequestQueryParameters.add_parameter_fields(
|
|
310
|
+
cls,
|
|
311
|
+
{
|
|
312
|
+
parameter_field.name: FieldInfo.from_annotated_attribute(
|
|
313
|
+
parameter_field.annotation, parameter_field.default
|
|
314
|
+
)
|
|
315
|
+
for option in cls.get_request_options()
|
|
316
|
+
for parameter_field in option.get_parameter_fields()
|
|
317
|
+
if parameter_field.name not in cls.model_fields
|
|
318
|
+
},
|
|
319
|
+
raise_errors=False,
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
@classmethod
|
|
323
|
+
def prepare_parameters(cls) -> None:
|
|
324
|
+
"""Adds the parameters of ``Meta.filters`` and describes the filter parameters the class
|
|
325
|
+
declares, from the ORM's descriptions of their filters - once per class. It needs the
|
|
326
|
+
models bound (``Hare.bind_models()`` or ``Hare.init()``), not the connections:
|
|
327
|
+
a framework adapter calls it before it reads the parameters for the handlers' signatures,
|
|
328
|
+
and the query calls it when it is first built.
|
|
329
|
+
|
|
330
|
+
Raises:
|
|
331
|
+
ConfigurationError: ``Meta.filters`` is wrong - see ``FilterParameterBuilder`` - or the
|
|
332
|
+
queryset's model was unregistered.
|
|
333
|
+
"""
|
|
334
|
+
if cls in RequestQuery.prepared_classes:
|
|
335
|
+
return
|
|
336
|
+
queryset = cls.get_meta_option("queryset")
|
|
337
|
+
if isinstance(queryset, QuerySet):
|
|
338
|
+
RequestQueryRegistry.check_model_registered(cls, queryset.model)
|
|
339
|
+
builder = FilterParameterBuilder(cls)
|
|
340
|
+
fields = builder.build_fields(queryset)
|
|
341
|
+
RequestQuery.unprepared_fields.setdefault(cls, dict(cls.__pydantic_fields__))
|
|
342
|
+
RequestQueryParameters.add_parameter_fields(cls, fields)
|
|
343
|
+
RequestQueryRegistry.track_models(cls, {queryset.model, *builder.described_models})
|
|
344
|
+
RequestQuery.bound_models.add(queryset.model)
|
|
345
|
+
RequestQuery.prepared_classes.add(cls)
|
|
346
|
+
|
|
347
|
+
@classmethod
|
|
348
|
+
def forget_model(cls, model: type[Model]) -> None:
|
|
349
|
+
"""Forgets the declaration and the prepared parameters of every request query class that
|
|
350
|
+
read ``model`` - one on it, or whose filters, search, orderings, fields or include cross
|
|
351
|
+
it. The next use builds them again from the model as it is now.
|
|
352
|
+
|
|
353
|
+
Args:
|
|
354
|
+
model: The model that changed.
|
|
355
|
+
"""
|
|
356
|
+
for request_query_class in list(RequestQuery.classes_by_model.pop(model, ())):
|
|
357
|
+
RequestQueryRegistry.forget_parameters(cast("type[RequestQuery[Any]]", request_query_class))
|
|
358
|
+
|
|
359
|
+
@classmethod
|
|
360
|
+
def forget_all(cls) -> None:
|
|
361
|
+
"""Forgets the declaration and the prepared parameters of every request query class."""
|
|
362
|
+
request_query_classes = {*RequestQuery.declarations.owners, *RequestQuery.prepared_classes}
|
|
363
|
+
RequestQuery.classes_by_model.clear()
|
|
364
|
+
for request_query_class in request_query_classes:
|
|
365
|
+
RequestQueryRegistry.forget_parameters(cast("type[RequestQuery[Any]]", request_query_class))
|
|
366
|
+
|
|
367
|
+
@classmethod
|
|
368
|
+
def get_request_options(cls) -> tuple[RequestOption, ...]:
|
|
369
|
+
"""The class's ``Meta`` options that add parameters.
|
|
370
|
+
|
|
371
|
+
Returns:
|
|
372
|
+
The options that are set.
|
|
373
|
+
"""
|
|
374
|
+
bucket = cls.get_cache_bucket()
|
|
375
|
+
options: tuple[RequestOption, ...] | None = bucket.get(REQUEST_OPTIONS_BUCKET_KEY)
|
|
376
|
+
if options is None:
|
|
377
|
+
options = bucket[REQUEST_OPTIONS_BUCKET_KEY] = tuple(
|
|
378
|
+
option
|
|
379
|
+
for option_name in PARAMETER_OPTION_NAMES
|
|
380
|
+
if isinstance(option := cls.get_meta_option(option_name), RequestOption)
|
|
381
|
+
)
|
|
382
|
+
return options
|
|
383
|
+
|
|
384
|
+
@classmethod
|
|
385
|
+
def get_declaration(cls) -> RequestQueryDeclaration:
|
|
386
|
+
"""The class's checked declaration, built the first time it is asked for.
|
|
387
|
+
|
|
388
|
+
Returns:
|
|
389
|
+
The declaration.
|
|
390
|
+
|
|
391
|
+
Raises:
|
|
392
|
+
ConfigurationError: The class is a base without a queryset, declares a filter, search
|
|
393
|
+
or ordering the model doesn't have or the class's dialects don't run, or its
|
|
394
|
+
queryset's model was unregistered.
|
|
395
|
+
"""
|
|
396
|
+
declarations = cls.get_cache_bucket()
|
|
397
|
+
declaration = declarations.get(DECLARATION_BUCKET_KEY)
|
|
398
|
+
# A registration while the declaration is built (a driver or dialect loaded on first use)
|
|
399
|
+
# forgets the half-prepared class - its parameters are put back - so it is built again.
|
|
400
|
+
while declaration is None:
|
|
401
|
+
queryset = cls.get_meta_option("queryset")
|
|
402
|
+
if isinstance(queryset, QuerySet):
|
|
403
|
+
RequestQueryRegistry.check_model_registered(cls, queryset.model)
|
|
404
|
+
cls.prepare_parameters()
|
|
405
|
+
builder = DeclarationBuilder(cls)
|
|
406
|
+
built_declaration = dataclasses.replace(
|
|
407
|
+
builder.build(), on_describe=partial(RequestQueryRegistry.track_described_models, ref(cls))
|
|
408
|
+
)
|
|
409
|
+
if cls not in RequestQuery.prepared_classes:
|
|
410
|
+
continue
|
|
411
|
+
RequestQueryRegistry.track_models(cls, builder.described_models)
|
|
412
|
+
declaration = declarations[DECLARATION_BUCKET_KEY] = built_declaration
|
|
413
|
+
return cast("RequestQueryDeclaration", declaration)
|
|
414
|
+
|
|
415
|
+
@classmethod
|
|
416
|
+
def for_model[FactoryModel: Model](
|
|
417
|
+
cls,
|
|
418
|
+
model: type[FactoryModel],
|
|
419
|
+
*,
|
|
420
|
+
name: str | None = None,
|
|
421
|
+
queryset: QuerySet[FactoryModel] | None = None,
|
|
422
|
+
filters: tuple[FilterField, ...] | None = Meta.filters,
|
|
423
|
+
search: SearchConfig | None = Meta.search,
|
|
424
|
+
ordering: OrderingConfig | None = Meta.ordering,
|
|
425
|
+
pagination: Pagination | None = Meta.pagination,
|
|
426
|
+
fields: FieldsConfig | None = Meta.fields,
|
|
427
|
+
include: IncludeConfig | None = Meta.include,
|
|
428
|
+
deleted: DeletedConfig | None = Meta.deleted,
|
|
429
|
+
versions: LatestVersions | None = Meta.versions,
|
|
430
|
+
join_type: Connector = Meta.join_type,
|
|
431
|
+
) -> type[RequestQuery[FactoryModel]]:
|
|
432
|
+
"""A request query class of a model known only while the application runs - one
|
|
433
|
+
registered with ``Hare.register_live_models()`` - built and checked at once::
|
|
434
|
+
|
|
435
|
+
ContentQuery = RequestQuery.for_model(
|
|
436
|
+
content_model,
|
|
437
|
+
filters=(FilterField("status", lookups=(Lookup.EXACT, Lookup.IN)),),
|
|
438
|
+
ordering=OrderingConfig(fields=("title",)),
|
|
439
|
+
)
|
|
440
|
+
|
|
441
|
+
The class is held weakly like any other: once nothing holds it, it leaves the
|
|
442
|
+
declarations and ``get_concrete_subclasses()``. Called on a dialect's request query,
|
|
443
|
+
the class is of that dialect.
|
|
444
|
+
|
|
445
|
+
Args:
|
|
446
|
+
model: The model - bound, so its filters can be checked.
|
|
447
|
+
name: The class's name, ``<Model>RequestQuery`` by default.
|
|
448
|
+
queryset: The rows the query starts from - ``model.objects`` by default.
|
|
449
|
+
filters: ``Meta.filters``.
|
|
450
|
+
search: ``Meta.search``.
|
|
451
|
+
ordering: ``Meta.ordering``.
|
|
452
|
+
pagination: ``Meta.pagination`` - an ``OffsetPagination()`` by default.
|
|
453
|
+
fields: ``Meta.fields``.
|
|
454
|
+
include: ``Meta.include``.
|
|
455
|
+
deleted: ``Meta.deleted``.
|
|
456
|
+
versions: ``Meta.versions``.
|
|
457
|
+
join_type: ``Meta.join_type``.
|
|
458
|
+
|
|
459
|
+
Returns:
|
|
460
|
+
The request query class.
|
|
461
|
+
|
|
462
|
+
Raises:
|
|
463
|
+
ConfigurationError: ``model`` isn't a model, ``queryset`` is of another model, ``name``
|
|
464
|
+
isn't an identifier, or the declaration is wrong - as ``check_declarations()``
|
|
465
|
+
finds it.
|
|
466
|
+
"""
|
|
467
|
+
if not (isinstance(model, type) and issubclass(model, Model)):
|
|
468
|
+
raise ConfigurationError(f"{cls.__qualname__}.for_model() takes a model class, got {model!r}")
|
|
469
|
+
if queryset is None:
|
|
470
|
+
queryset = model.objects.all()
|
|
471
|
+
elif not isinstance(queryset, QuerySet) or queryset.model is not model:
|
|
472
|
+
raise ConfigurationError(
|
|
473
|
+
f"{cls.__qualname__}.for_model({model.__name__}) takes a queryset of {model.__name__}, "
|
|
474
|
+
f"got {queryset!r}"
|
|
475
|
+
)
|
|
476
|
+
class_name = name if name is not None else f"{model.__name__}RequestQuery"
|
|
477
|
+
if not isinstance(class_name, str) or not class_name.isidentifier():
|
|
478
|
+
raise ConfigurationError(f"{cls.__qualname__}.for_model() name must be an identifier, got {class_name!r}")
|
|
479
|
+
# Named as a class nested in the new one - pydantic leaves such a class out of the fields.
|
|
480
|
+
meta = type(
|
|
481
|
+
META_CLASS_NAME,
|
|
482
|
+
(),
|
|
483
|
+
{
|
|
484
|
+
"__module__": cls.__module__,
|
|
485
|
+
"__qualname__": f"{class_name}.{META_CLASS_NAME}",
|
|
486
|
+
"queryset": queryset,
|
|
487
|
+
"filters": filters,
|
|
488
|
+
"search": search,
|
|
489
|
+
"ordering": ordering,
|
|
490
|
+
"pagination": pagination,
|
|
491
|
+
"fields": fields,
|
|
492
|
+
"include": include,
|
|
493
|
+
"deleted": deleted,
|
|
494
|
+
"versions": versions,
|
|
495
|
+
"join_type": join_type,
|
|
496
|
+
},
|
|
497
|
+
)
|
|
498
|
+
base = cls[model] if cls.__pydantic_generic_metadata__["parameters"] else cls # type: ignore[index]
|
|
499
|
+
request_query_class = cast(
|
|
500
|
+
"type[RequestQuery[FactoryModel]]",
|
|
501
|
+
type(
|
|
502
|
+
class_name, (base,), {"__module__": cls.__module__, "__qualname__": class_name, META_CLASS_NAME: meta}
|
|
503
|
+
),
|
|
504
|
+
)
|
|
505
|
+
request_query_class.check_declaration()
|
|
506
|
+
return request_query_class
|
|
507
|
+
|
|
508
|
+
@classmethod
|
|
509
|
+
def describe_parameters(cls) -> tuple[ParameterDescription, ...]:
|
|
510
|
+
"""What each parameter of the class is - for building a UI over it: a filter's key, path,
|
|
511
|
+
lookup, value and relation, the bound it pairs with, the choices of an enum and of an
|
|
512
|
+
option. Needs the models bound, not the connections, as ``get_declaration()``; a class
|
|
513
|
+
forgotten with its model (a live model registered again) describes the model as it is now.
|
|
514
|
+
|
|
515
|
+
Returns:
|
|
516
|
+
One description per parameter, in the parameters' order.
|
|
517
|
+
|
|
518
|
+
Raises:
|
|
519
|
+
ConfigurationError: See ``get_declaration()``.
|
|
520
|
+
"""
|
|
521
|
+
return ParameterDescriber(cls).describe()
|
|
522
|
+
|
|
523
|
+
@classmethod
|
|
524
|
+
def check_declaration(cls) -> None:
|
|
525
|
+
"""Builds and checks the class's declaration afresh - ``check_declarations()`` for one
|
|
526
|
+
class.
|
|
527
|
+
|
|
528
|
+
Raises:
|
|
529
|
+
ConfigurationError: See ``get_declaration()``.
|
|
530
|
+
"""
|
|
531
|
+
RequestQuery.declarations.forget_owner(cls)
|
|
532
|
+
cls.get_declaration()
|
|
533
|
+
|
|
534
|
+
@classmethod
|
|
535
|
+
def check_declarations(cls) -> None:
|
|
536
|
+
"""Builds and checks the declaration of every request query class below this one whose
|
|
537
|
+
queryset's model is registered in the current Hare context - an application calls it once
|
|
538
|
+
its models are set up, so a wrong declaration fails at startup, not on the first request.
|
|
539
|
+
A class of a model the context doesn't have belongs to another application and is skipped.
|
|
540
|
+
|
|
541
|
+
Raises:
|
|
542
|
+
ConfigurationError: A declaration is wrong - every wrong one is listed - or no Hare
|
|
543
|
+
context is active.
|
|
544
|
+
"""
|
|
545
|
+
apps = HareContext.require_current().apps
|
|
546
|
+
registered_models = set(apps.get_models_iterable()) if apps is not None else set()
|
|
547
|
+
errors = []
|
|
548
|
+
for request_query_class in cls.get_concrete_subclasses():
|
|
549
|
+
queryset = request_query_class.get_meta_option("queryset")
|
|
550
|
+
if isinstance(queryset, QuerySet) and queryset.model not in registered_models:
|
|
551
|
+
continue
|
|
552
|
+
try:
|
|
553
|
+
request_query_class.check_declaration()
|
|
554
|
+
except ConfigurationError as error:
|
|
555
|
+
errors.append(str(error))
|
|
556
|
+
if errors:
|
|
557
|
+
raise ConfigurationError("Wrong request queries:\n" + "\n".join(errors))
|
|
558
|
+
|
|
559
|
+
@classmethod
|
|
560
|
+
def get_concrete_subclasses(cls) -> list[type[RequestQuery[Any]]]:
|
|
561
|
+
"""The classes below this one that declare a queryset.
|
|
562
|
+
|
|
563
|
+
Returns:
|
|
564
|
+
The classes, each once.
|
|
565
|
+
"""
|
|
566
|
+
found: dict[type[RequestQuery[Any]], None] = {}
|
|
567
|
+
pending: list[type[RequestQuery[Any]]] = list(cls.__subclasses__())
|
|
568
|
+
while pending:
|
|
569
|
+
subclass = pending.pop()
|
|
570
|
+
if subclass in found:
|
|
571
|
+
continue
|
|
572
|
+
if (
|
|
573
|
+
subclass.get_meta_option("queryset") is not None
|
|
574
|
+
and not subclass.__pydantic_generic_metadata__["origin"]
|
|
575
|
+
):
|
|
576
|
+
found[subclass] = None
|
|
577
|
+
pending.extend(subclass.__subclasses__())
|
|
578
|
+
return list(found)
|
|
579
|
+
|
|
580
|
+
@property
|
|
581
|
+
def request(self) -> Any:
|
|
582
|
+
"""The request the parameters came from, None when built without one."""
|
|
583
|
+
return self._request
|
|
584
|
+
|
|
585
|
+
def get_request_url(self) -> str | None:
|
|
586
|
+
"""The address of the request, with its query string - the links of a page are built from
|
|
587
|
+
it.
|
|
588
|
+
|
|
589
|
+
Returns:
|
|
590
|
+
The address a framework adapter set, else the request's ``url`` as text; None without
|
|
591
|
+
either.
|
|
592
|
+
"""
|
|
593
|
+
if self._request_url is not None:
|
|
594
|
+
return self._request_url
|
|
595
|
+
url = getattr(self._request, "url", None)
|
|
596
|
+
return None if url is None else str(url)
|
|
597
|
+
|
|
598
|
+
def set_request_url(self, url: str) -> None:
|
|
599
|
+
"""Sets the address of the request - for a framework whose request's ``url`` isn't the
|
|
600
|
+
whole address with its query string.
|
|
601
|
+
|
|
602
|
+
Args:
|
|
603
|
+
url: The address.
|
|
604
|
+
"""
|
|
605
|
+
self._request_url = url
|
|
606
|
+
|
|
607
|
+
def cache_key(self) -> str:
|
|
608
|
+
"""A key naming the query and the values of its parameters, the same for the same request -
|
|
609
|
+
for caching its result together with whatever else the result depends on (the user).
|
|
610
|
+
|
|
611
|
+
Returns:
|
|
612
|
+
The class's path and its parameter values as JSON.
|
|
613
|
+
"""
|
|
614
|
+
values = self.model_dump(mode="json", exclude_none=True)
|
|
615
|
+
return f"{type(self).__module__}.{type(self).__qualname__}:{json.dumps(values, sort_keys=True)}"
|
|
616
|
+
|
|
617
|
+
def get_queryset(self) -> QuerySet[ModelType]:
|
|
618
|
+
"""The rows the query starts from - a copy of ``Meta.queryset``. Override it for rows that
|
|
619
|
+
depend on the request; filters on annotations still need them in ``Meta.queryset``, which
|
|
620
|
+
the declaration is checked against.
|
|
621
|
+
|
|
622
|
+
Returns:
|
|
623
|
+
The queryset.
|
|
624
|
+
"""
|
|
625
|
+
return self.get_declaration().queryset.all()
|
|
626
|
+
|
|
627
|
+
def where(self, *conditions: Q, **filters: Any) -> Self:
|
|
628
|
+
"""Adds conditions of the handler's own to the request's - they join with ``AND``.
|
|
629
|
+
|
|
630
|
+
Args:
|
|
631
|
+
conditions: ``Q`` conditions.
|
|
632
|
+
filters: ``.filter()`` keyword conditions.
|
|
633
|
+
|
|
634
|
+
Returns:
|
|
635
|
+
The query itself.
|
|
636
|
+
"""
|
|
637
|
+
if conditions or filters:
|
|
638
|
+
self._conditions = (*self._conditions, Q(*conditions, **filters))
|
|
639
|
+
return self
|
|
640
|
+
|
|
641
|
+
def order_by(self, *names: OrderingItem) -> Self:
|
|
642
|
+
"""Orders the rows by the handler's choice instead of the request's or the default one.
|
|
643
|
+
|
|
644
|
+
Args:
|
|
645
|
+
names: Ordering names, ``-`` for descending, or ordering expressions.
|
|
646
|
+
|
|
647
|
+
Returns:
|
|
648
|
+
The query itself.
|
|
649
|
+
"""
|
|
650
|
+
self._explicit_ordering = names
|
|
651
|
+
return self
|
|
652
|
+
|
|
653
|
+
def select_related(self, *fields: str) -> Self:
|
|
654
|
+
"""Loads related rows along with the rows.
|
|
655
|
+
|
|
656
|
+
Args:
|
|
657
|
+
fields: Relations, as for ``QuerySet.select_related()``.
|
|
658
|
+
|
|
659
|
+
Returns:
|
|
660
|
+
The query itself.
|
|
661
|
+
"""
|
|
662
|
+
self._queryset_changes = (*self._queryset_changes, lambda queryset: queryset.select_related(*fields))
|
|
663
|
+
return self
|
|
664
|
+
|
|
665
|
+
def prefetch_related(self, *lookups: Any) -> Self:
|
|
666
|
+
"""Loads related rows with separate queries.
|
|
667
|
+
|
|
668
|
+
Args:
|
|
669
|
+
lookups: Relations or ``Prefetch`` objects, as for ``QuerySet.prefetch_related()``.
|
|
670
|
+
|
|
671
|
+
Returns:
|
|
672
|
+
The query itself.
|
|
673
|
+
"""
|
|
674
|
+
self._queryset_changes = (*self._queryset_changes, lambda queryset: queryset.prefetch_related(*lookups))
|
|
675
|
+
return self
|
|
676
|
+
|
|
677
|
+
def annotate(self, **annotations: Any) -> Self:
|
|
678
|
+
"""Adds annotations to the rows.
|
|
679
|
+
|
|
680
|
+
Args:
|
|
681
|
+
annotations: Annotations by name, as for ``QuerySet.annotate()``.
|
|
682
|
+
|
|
683
|
+
Returns:
|
|
684
|
+
The query itself.
|
|
685
|
+
"""
|
|
686
|
+
self._queryset_changes = (*self._queryset_changes, lambda queryset: queryset.annotate(**annotations))
|
|
687
|
+
return self
|
|
688
|
+
|
|
689
|
+
async def may_see_deleted(self) -> bool:
|
|
690
|
+
"""Whether the request may see soft-deleted rows - override it with the application's
|
|
691
|
+
access rules. It is asked only when the request asks for deleted rows with
|
|
692
|
+
``Meta.deleted``'s parameter.
|
|
693
|
+
|
|
694
|
+
Returns:
|
|
695
|
+
True by default - declaring ``Meta.deleted`` lets every request see them.
|
|
696
|
+
"""
|
|
697
|
+
return True
|
|
698
|
+
|
|
699
|
+
async def apply_deleted(self, queryset: QuerySet[ModelType]) -> QuerySet[ModelType]:
|
|
700
|
+
"""Includes or selects the soft-deleted rows the request asks for with ``Meta.deleted``.
|
|
701
|
+
|
|
702
|
+
Args:
|
|
703
|
+
queryset: A queryset of the model.
|
|
704
|
+
|
|
705
|
+
Returns:
|
|
706
|
+
The queryset - unchanged without ``Meta.deleted`` or when the request asks for none.
|
|
707
|
+
|
|
708
|
+
Raises:
|
|
709
|
+
RequestQueryForbidden: The request asks for deleted rows ``may_see_deleted()`` doesn't
|
|
710
|
+
allow it to see.
|
|
711
|
+
"""
|
|
712
|
+
deleted = self.get_declaration().deleted
|
|
713
|
+
if deleted is None:
|
|
714
|
+
return queryset
|
|
715
|
+
deleted_rows = deleted.get_requested(RequestQueryParameters.get_parameter_values(self))
|
|
716
|
+
if deleted_rows is not DeletedRows.EXCLUDE and not await self.may_see_deleted():
|
|
717
|
+
raise RequestQueryForbidden(deleted.parameter, "The request may not see deleted rows")
|
|
718
|
+
return deleted.apply(queryset, deleted_rows)
|
|
719
|
+
|
|
720
|
+
async def get_rows_queryset(self) -> QuerySet[ModelType]:
|
|
721
|
+
"""The rows the query starts from with the handler's changes and the deleted rows the
|
|
722
|
+
request asks for - before any condition.
|
|
723
|
+
|
|
724
|
+
Returns:
|
|
725
|
+
The queryset.
|
|
726
|
+
|
|
727
|
+
Raises:
|
|
728
|
+
RequestQueryForbidden: See ``apply_deleted()``.
|
|
729
|
+
"""
|
|
730
|
+
queryset = await self.apply_deleted(self.get_queryset())
|
|
731
|
+
for change in self._queryset_changes:
|
|
732
|
+
queryset = change(queryset)
|
|
733
|
+
return queryset
|
|
734
|
+
|
|
735
|
+
async def get_access_condition(self) -> Q | None:
|
|
736
|
+
"""The rows the request may see at all - override it with the application's access rules
|
|
737
|
+
(the request's user, its roles). It joins every query with ``AND``, ``delete()`` included.
|
|
738
|
+
|
|
739
|
+
Returns:
|
|
740
|
+
The condition, None for every row.
|
|
741
|
+
"""
|
|
742
|
+
return None
|
|
743
|
+
|
|
744
|
+
async def after_fetch(self, items: list[ModelType]) -> list[ModelType]:
|
|
745
|
+
"""Runs on the rows of ``fetch()``, ``page()`` and ``get()`` once they are fetched - override
|
|
746
|
+
it to load what the rows need from elsewhere.
|
|
747
|
+
|
|
748
|
+
Args:
|
|
749
|
+
items: The rows.
|
|
750
|
+
|
|
751
|
+
Returns:
|
|
752
|
+
The rows to return.
|
|
753
|
+
"""
|
|
754
|
+
return items
|
|
755
|
+
|
|
756
|
+
async def get_request_conditions(self, *, skipped_target: ValueTarget | None = None) -> list[Q]:
|
|
757
|
+
"""The conditions of the request's parameters and search. The async ``filter_<parameter>``
|
|
758
|
+
methods of the parameters with a value run concurrently; the conditions keep the order the
|
|
759
|
+
parameters are declared in.
|
|
760
|
+
|
|
761
|
+
Args:
|
|
762
|
+
skipped_target: The values whose own filters are left out - ``count_by()`` counts a
|
|
763
|
+
field under every filter of the request but its own.
|
|
764
|
+
|
|
765
|
+
Returns:
|
|
766
|
+
The parameters' conditions joined by ``Meta.join_type`` as one condition, and the
|
|
767
|
+
search's as another; an empty list when the request filters by nothing.
|
|
768
|
+
|
|
769
|
+
Raises:
|
|
770
|
+
TypeError: A filter method returned something other than a ``Q`` or None.
|
|
771
|
+
"""
|
|
772
|
+
declaration = self.get_declaration()
|
|
773
|
+
# Each parameter's condition in declaration order, with the method that gave it: an async
|
|
774
|
+
# filter method's is awaited below, every one of them at once.
|
|
775
|
+
method_conditions: list[tuple[str | None, Any]] = []
|
|
776
|
+
for filter_declaration in declaration.filters:
|
|
777
|
+
value = getattr(self, filter_declaration.parameter)
|
|
778
|
+
if value is None or self.is_skipped(filter_declaration, skipped_target):
|
|
779
|
+
continue
|
|
780
|
+
if filter_declaration.method_name is not None:
|
|
781
|
+
method = getattr(self, filter_declaration.method_name)
|
|
782
|
+
method_conditions.append((filter_declaration.method_name, method(value)))
|
|
783
|
+
continue
|
|
784
|
+
method_conditions.append((None, Q(**{cast("str", filter_declaration.filter_key): value})))
|
|
785
|
+
pending_positions = [
|
|
786
|
+
position for position, (__, condition) in enumerate(method_conditions) if inspect.isawaitable(condition)
|
|
787
|
+
]
|
|
788
|
+
if pending_positions:
|
|
789
|
+
awaited_conditions = await asyncio.gather(
|
|
790
|
+
*(method_conditions[position][1] for position in pending_positions)
|
|
791
|
+
)
|
|
792
|
+
for position, condition in zip(pending_positions, awaited_conditions, strict=True):
|
|
793
|
+
method_conditions[position] = (method_conditions[position][0], condition)
|
|
794
|
+
filter_conditions: list[Q] = []
|
|
795
|
+
for method_name, condition in method_conditions:
|
|
796
|
+
if condition is None:
|
|
797
|
+
continue
|
|
798
|
+
if not isinstance(condition, Q):
|
|
799
|
+
raise TypeError(
|
|
800
|
+
f"{type(self).__qualname__}.{method_name}() must return a Q or None, got {condition!r}"
|
|
801
|
+
)
|
|
802
|
+
filter_conditions.append(condition)
|
|
803
|
+
conditions = []
|
|
804
|
+
if filter_conditions:
|
|
805
|
+
conditions.append(Q.with_connector(declaration.join_type, *filter_conditions))
|
|
806
|
+
search_condition = self.get_search_condition()
|
|
807
|
+
if search_condition is not None:
|
|
808
|
+
conditions.append(search_condition)
|
|
809
|
+
return conditions
|
|
810
|
+
|
|
811
|
+
def get_search_condition(self) -> Q | None:
|
|
812
|
+
"""The condition of the request's search.
|
|
813
|
+
|
|
814
|
+
Returns:
|
|
815
|
+
The condition, None without a search or a search text.
|
|
816
|
+
"""
|
|
817
|
+
search = self.get_declaration().search
|
|
818
|
+
return None if search is None else search.get_condition(RequestQueryParameters.get_parameter_values(self))
|
|
819
|
+
|
|
820
|
+
def crosses_to_many(self, queryset: QuerySet[Any], condition: Q) -> bool:
|
|
821
|
+
"""Whether a condition joins a relation to many rows - the query can then return a row more
|
|
822
|
+
than once.
|
|
823
|
+
|
|
824
|
+
Args:
|
|
825
|
+
queryset: The queryset the condition filters.
|
|
826
|
+
condition: The condition.
|
|
827
|
+
|
|
828
|
+
Returns:
|
|
829
|
+
True when a filter key of the condition or of a condition inside it crosses such a
|
|
830
|
+
relation.
|
|
831
|
+
|
|
832
|
+
Raises:
|
|
833
|
+
FieldError: A filter key names no field, relation or annotation.
|
|
834
|
+
"""
|
|
835
|
+
declaration = self.get_declaration()
|
|
836
|
+
return any(declaration.get_lookup_info(queryset, key).crosses_to_many for key in condition.filters) or any(
|
|
837
|
+
self.crosses_to_many(queryset, child) for child in condition.children
|
|
838
|
+
)
|
|
839
|
+
|
|
840
|
+
async def build_queryset(
|
|
841
|
+
self,
|
|
842
|
+
method_name: str,
|
|
843
|
+
*,
|
|
844
|
+
each_row_once: EachRowOnce,
|
|
845
|
+
skipped_target: ValueTarget | None = None,
|
|
846
|
+
needs_filter: bool = False,
|
|
847
|
+
) -> QuerySet[ModelType]:
|
|
848
|
+
"""The queryset with the handler's changes and every condition: the request's parameters
|
|
849
|
+
and search, the handler's ``where()``, the access condition, the latest versions.
|
|
850
|
+
|
|
851
|
+
Args:
|
|
852
|
+
method_name: The method asking, for the error.
|
|
853
|
+
each_row_once: How to take each row once when a condition joins a relation to many
|
|
854
|
+
rows.
|
|
855
|
+
skipped_target: The values whose own filters are left out.
|
|
856
|
+
needs_filter: Refuse a request nothing but the access condition filters - a delete or an
|
|
857
|
+
update never changes every row the user may see.
|
|
858
|
+
|
|
859
|
+
Returns:
|
|
860
|
+
The queryset, not ordered.
|
|
861
|
+
|
|
862
|
+
Raises:
|
|
863
|
+
RequestQueryForbidden: See ``apply_deleted()``.
|
|
864
|
+
QueryError: See ``get_rows_once()``.
|
|
865
|
+
InvalidRequestQuery: ``needs_filter`` and neither the request's parameters and search nor
|
|
866
|
+
the handler's ``where()`` give a condition - a filter method returning None gives
|
|
867
|
+
none; the request's fault, answered as an invalid request.
|
|
868
|
+
"""
|
|
869
|
+
queryset = await self.get_rows_queryset()
|
|
870
|
+
conditions = [*await self.get_request_conditions(skipped_target=skipped_target), *self._conditions]
|
|
871
|
+
if needs_filter and not any(conditions):
|
|
872
|
+
raise InvalidRequestQuery(
|
|
873
|
+
[
|
|
874
|
+
{
|
|
875
|
+
"loc": [],
|
|
876
|
+
"msg": f"{type(self).__qualname__}.{method_name}() needs a filter - the request filters "
|
|
877
|
+
"by nothing",
|
|
878
|
+
"type": MISSING_FILTER_ERROR_TYPE,
|
|
879
|
+
}
|
|
880
|
+
]
|
|
881
|
+
)
|
|
882
|
+
access_condition = await self.get_access_condition()
|
|
883
|
+
if access_condition is not None:
|
|
884
|
+
conditions.append(access_condition)
|
|
885
|
+
versions = self.get_declaration().versions
|
|
886
|
+
if versions is not None:
|
|
887
|
+
all_versions = await self.apply_deleted(self.get_queryset())
|
|
888
|
+
conditions.append(versions.get_condition(all_versions, access_condition))
|
|
889
|
+
if not conditions:
|
|
890
|
+
return queryset
|
|
891
|
+
queryset = queryset.filter(*conditions)
|
|
892
|
+
if each_row_once is EachRowOnce.NOT_NEEDED or not any(
|
|
893
|
+
self.crosses_to_many(queryset, condition) for condition in conditions
|
|
894
|
+
):
|
|
895
|
+
return queryset
|
|
896
|
+
if each_row_once is EachRowOnce.DISTINCT:
|
|
897
|
+
return queryset.distinct()
|
|
898
|
+
return await self.get_rows_once(queryset, method_name)
|
|
899
|
+
|
|
900
|
+
@staticmethod
|
|
901
|
+
def is_skipped(filter_declaration: FilterDeclaration, skipped_target: ValueTarget | None) -> bool:
|
|
902
|
+
"""Whether a filter is one of the left-out values' own.
|
|
903
|
+
|
|
904
|
+
Args:
|
|
905
|
+
filter_declaration: The filter.
|
|
906
|
+
skipped_target: The left-out values, None for none.
|
|
907
|
+
|
|
908
|
+
Returns:
|
|
909
|
+
True when the filter compares those values - a filter method never is.
|
|
910
|
+
"""
|
|
911
|
+
if skipped_target is None or filter_declaration.lookup_info is None:
|
|
912
|
+
return False
|
|
913
|
+
return ValueTarget.of(filter_declaration.lookup_info) == skipped_target
|
|
914
|
+
|
|
915
|
+
async def get_filtered_queryset(self) -> QuerySet[ModelType]:
|
|
916
|
+
"""The rows the request asks for, each once, not ordered - for what the methods below don't
|
|
917
|
+
do.
|
|
918
|
+
|
|
919
|
+
Returns:
|
|
920
|
+
The queryset.
|
|
921
|
+
"""
|
|
922
|
+
return await self.build_queryset("get_filtered_queryset", each_row_once=EachRowOnce.DISTINCT)
|
|
923
|
+
|
|
924
|
+
def get_ordering(self, queryset: QuerySet[ModelType]) -> tuple[OrderingItem, ...]:
|
|
925
|
+
"""The ordering of the rows: the handler's ``order_by()``, else the request's, else
|
|
926
|
+
``OrderingConfig.default``, else the queryset's own, else the model's ``Meta.ordering`` - and
|
|
927
|
+
then the primary key's fields that aren't ordered by yet, so equal values keep one order. A
|
|
928
|
+
model without a primary key gets no such fields.
|
|
929
|
+
|
|
930
|
+
Args:
|
|
931
|
+
queryset: The queryset being ordered.
|
|
932
|
+
|
|
933
|
+
Returns:
|
|
934
|
+
The ordering.
|
|
935
|
+
"""
|
|
936
|
+
declaration = self.get_declaration()
|
|
937
|
+
ordering = declaration.ordering
|
|
938
|
+
items: tuple[OrderingItem, ...] = ()
|
|
939
|
+
if self._explicit_ordering is not None:
|
|
940
|
+
items = self._explicit_ordering
|
|
941
|
+
elif ordering is not None and (
|
|
942
|
+
requested := ordering.get_requested(RequestQueryParameters.get_parameter_values(self))
|
|
943
|
+
):
|
|
944
|
+
items = requested
|
|
945
|
+
elif ordering is not None and ordering.default:
|
|
946
|
+
items = ordering.default
|
|
947
|
+
elif queryset.orderings:
|
|
948
|
+
items = tuple(Ordering(field_name, order) for field_name, order in queryset.orderings)
|
|
949
|
+
elif queryset.model._meta.ordering:
|
|
950
|
+
ordering_expressions = queryset.model._meta.ordering_expressions
|
|
951
|
+
items = tuple(
|
|
952
|
+
Ordering(ordering_expressions.get(field_name, field_name), order)
|
|
953
|
+
for field_name, order in queryset.model._meta.ordering
|
|
954
|
+
)
|
|
955
|
+
if not declaration.key_ordering_paths:
|
|
956
|
+
return items
|
|
957
|
+
ordered_paths = {path for item in items for path in self.get_ordering_info(queryset, item).paths}
|
|
958
|
+
return (*items, *(path for path in declaration.key_ordering_paths if path not in ordered_paths))
|
|
959
|
+
|
|
960
|
+
@staticmethod
|
|
961
|
+
def get_ordering_name(item: OrderingItem) -> str:
|
|
962
|
+
"""The name of an ordering item without its direction.
|
|
963
|
+
|
|
964
|
+
Args:
|
|
965
|
+
item: A name with ``-`` for descending, or an ordering expression.
|
|
966
|
+
|
|
967
|
+
Returns:
|
|
968
|
+
The name.
|
|
969
|
+
"""
|
|
970
|
+
if not isinstance(item, Ordering):
|
|
971
|
+
return item.removeprefix(DESCENDING_PREFIX)
|
|
972
|
+
if not isinstance(item.target, str):
|
|
973
|
+
raise QueryError(
|
|
974
|
+
f"A request query orders by names - {item!r} orders by an expression; annotate it and order "
|
|
975
|
+
"by the annotation's name"
|
|
976
|
+
)
|
|
977
|
+
return item.target
|
|
978
|
+
|
|
979
|
+
def get_ordering_info(self, queryset: QuerySet[Any], item: OrderingItem) -> OrderingInfo:
|
|
980
|
+
"""The ORM's description of one ordering item, from the class's declaration - read once
|
|
981
|
+
per name, not on every request.
|
|
982
|
+
|
|
983
|
+
Args:
|
|
984
|
+
queryset: The queryset being ordered.
|
|
985
|
+
item: The ordering item.
|
|
986
|
+
|
|
987
|
+
Returns:
|
|
988
|
+
The description: the names the query orders by (a relation's key column, ``pk``'s key
|
|
989
|
+
fields), the fields and the relations crossed.
|
|
990
|
+
"""
|
|
991
|
+
return self.get_declaration().get_ordering_info(queryset, self.get_ordering_name(item))
|
|
992
|
+
|
|
993
|
+
def apply_selection(
|
|
994
|
+
self, queryset: QuerySet[ModelType], ordering: Iterable[OrderingItem] = ()
|
|
995
|
+
) -> QuerySet[ModelType]:
|
|
996
|
+
"""Loads what the request's fields and include parameters ask for: only the named fields
|
|
997
|
+
(with the primary key and the fields the ordering reads), and the named relations.
|
|
998
|
+
|
|
999
|
+
Args:
|
|
1000
|
+
queryset: The queryset of the rows.
|
|
1001
|
+
ordering: The ordering of the rows - its own fields are loaded too.
|
|
1002
|
+
|
|
1003
|
+
Returns:
|
|
1004
|
+
The queryset.
|
|
1005
|
+
"""
|
|
1006
|
+
declaration = self.get_declaration()
|
|
1007
|
+
parameter_values = RequestQueryParameters.get_parameter_values(self)
|
|
1008
|
+
if declaration.fields is not None:
|
|
1009
|
+
ordered_fields: list[str] = []
|
|
1010
|
+
for item in ordering:
|
|
1011
|
+
ordering_info = self.get_ordering_info(queryset, item)
|
|
1012
|
+
if not ordering_info.relations:
|
|
1013
|
+
ordered_fields.extend(ordering_info.paths)
|
|
1014
|
+
queryset = declaration.fields.apply(
|
|
1015
|
+
queryset, parameter_values, [*declaration.key_ordering_paths, *ordered_fields]
|
|
1016
|
+
)
|
|
1017
|
+
if declaration.include is not None:
|
|
1018
|
+
queryset = declaration.include.apply(queryset, parameter_values, declaration.include_to_many)
|
|
1019
|
+
return queryset
|
|
1020
|
+
|
|
1021
|
+
def get_ordered_queryset(self, queryset: QuerySet[ModelType]) -> QuerySet[ModelType]:
|
|
1022
|
+
"""A queryset ordered by ``get_ordering()``, loading what the request's fields and include
|
|
1023
|
+
parameters ask for.
|
|
1024
|
+
|
|
1025
|
+
Args:
|
|
1026
|
+
queryset: The filtered queryset.
|
|
1027
|
+
|
|
1028
|
+
Returns:
|
|
1029
|
+
The queryset.
|
|
1030
|
+
"""
|
|
1031
|
+
ordering = self.get_ordering(queryset)
|
|
1032
|
+
return self.apply_selection(queryset.order_by(*ordering), ordering)
|
|
1033
|
+
|
|
1034
|
+
@staticmethod
|
|
1035
|
+
@contextmanager
|
|
1036
|
+
def refusing_invalid_values() -> Iterator[None]:
|
|
1037
|
+
"""Refuses a value of the request its field or the database doesn't take - out of the
|
|
1038
|
+
column's range, too long, holding a null byte - as an invalid request.
|
|
1039
|
+
|
|
1040
|
+
Raises:
|
|
1041
|
+
InvalidRequestQuery: A field refused a value.
|
|
1042
|
+
"""
|
|
1043
|
+
try:
|
|
1044
|
+
yield
|
|
1045
|
+
except FieldValidationError as error:
|
|
1046
|
+
raise InvalidRequestQuery([{"loc": [], "msg": str(error), "type": INVALID_VALUE_ERROR_TYPE}]) from error
|
|
1047
|
+
|
|
1048
|
+
async def fetch(self) -> list[ModelType]:
|
|
1049
|
+
"""Every row the request asks for, ordered, without pagination.
|
|
1050
|
+
|
|
1051
|
+
Returns:
|
|
1052
|
+
The rows, after ``after_fetch()``.
|
|
1053
|
+
|
|
1054
|
+
Raises:
|
|
1055
|
+
InvalidRequestQuery: See ``refusing_invalid_values()``.
|
|
1056
|
+
"""
|
|
1057
|
+
with self.refusing_invalid_values():
|
|
1058
|
+
queryset = await self.get_filtered_queryset()
|
|
1059
|
+
items = list(await self.get_ordered_queryset(queryset))
|
|
1060
|
+
return await self.after_fetch(items)
|
|
1061
|
+
|
|
1062
|
+
async def page(self) -> Page[ModelType] | ScrollPage[ModelType] | CursorPage[ModelType]:
|
|
1063
|
+
"""The page of rows the request asks for - ``Meta.pagination`` builds it.
|
|
1064
|
+
|
|
1065
|
+
Returns:
|
|
1066
|
+
A ``Page`` of an ``OffsetPagination``, a ``ScrollPage`` of a ``ScrollPagination``, a
|
|
1067
|
+
``CursorPage`` of a ``CursorPagination``, or the page of a pagination of your own.
|
|
1068
|
+
|
|
1069
|
+
Raises:
|
|
1070
|
+
QueryError: The query has no pagination.
|
|
1071
|
+
InvalidRequestQuery: The request's cursor isn't a cursor of this query; see
|
|
1072
|
+
``refusing_invalid_values()``.
|
|
1073
|
+
"""
|
|
1074
|
+
pagination = self.get_declaration().pagination
|
|
1075
|
+
if pagination is None:
|
|
1076
|
+
raise QueryError(f"{type(self).__qualname__} has no Meta.pagination - use fetch()")
|
|
1077
|
+
with self.refusing_invalid_values():
|
|
1078
|
+
page = await pagination.get_page(self)
|
|
1079
|
+
return cast("Page[ModelType] | ScrollPage[ModelType] | CursorPage[ModelType]", page)
|
|
1080
|
+
|
|
1081
|
+
@overload
|
|
1082
|
+
async def get(
|
|
1083
|
+
self,
|
|
1084
|
+
*,
|
|
1085
|
+
does_not_exist_exception: None,
|
|
1086
|
+
multiple_objects_returned_exception: GetExceptionArgument = GetException.STANDARD,
|
|
1087
|
+
) -> ModelType | None: ...
|
|
1088
|
+
|
|
1089
|
+
@overload
|
|
1090
|
+
async def get(
|
|
1091
|
+
self,
|
|
1092
|
+
*,
|
|
1093
|
+
does_not_exist_exception: type[BaseException] | BaseException | GetException = GetException.STANDARD,
|
|
1094
|
+
multiple_objects_returned_exception: GetExceptionArgument = GetException.STANDARD,
|
|
1095
|
+
) -> ModelType: ...
|
|
1096
|
+
|
|
1097
|
+
async def get(
|
|
1098
|
+
self,
|
|
1099
|
+
*,
|
|
1100
|
+
does_not_exist_exception: GetExceptionArgument = GetException.STANDARD,
|
|
1101
|
+
multiple_objects_returned_exception: GetExceptionArgument = GetException.STANDARD,
|
|
1102
|
+
) -> ModelType | None:
|
|
1103
|
+
"""The one row the request asks for.
|
|
1104
|
+
|
|
1105
|
+
Args:
|
|
1106
|
+
does_not_exist_exception: As ``QuerySet.get()`` takes it - None gives None when no row
|
|
1107
|
+
matches.
|
|
1108
|
+
multiple_objects_returned_exception: As ``QuerySet.get()`` takes it - None reads one of
|
|
1109
|
+
the matching rows without counting them.
|
|
1110
|
+
|
|
1111
|
+
Returns:
|
|
1112
|
+
The row, after ``after_fetch()``; None when no row matches and
|
|
1113
|
+
``does_not_exist_exception`` is None.
|
|
1114
|
+
|
|
1115
|
+
Raises:
|
|
1116
|
+
DoesNotExist: No row matches.
|
|
1117
|
+
MultipleObjectsReturned: More than one row matches.
|
|
1118
|
+
InvalidRequestQuery: See ``refusing_invalid_values()``.
|
|
1119
|
+
"""
|
|
1120
|
+
with self.refusing_invalid_values():
|
|
1121
|
+
queryset = await self.get_filtered_queryset()
|
|
1122
|
+
item = await self.apply_selection(queryset).get(
|
|
1123
|
+
does_not_exist_exception=does_not_exist_exception,
|
|
1124
|
+
multiple_objects_returned_exception=multiple_objects_returned_exception,
|
|
1125
|
+
)
|
|
1126
|
+
if item is None:
|
|
1127
|
+
return None
|
|
1128
|
+
(item,) = await self.after_fetch([item])
|
|
1129
|
+
return item
|
|
1130
|
+
|
|
1131
|
+
async def count(self) -> int:
|
|
1132
|
+
"""How many rows the request asks for.
|
|
1133
|
+
|
|
1134
|
+
Returns:
|
|
1135
|
+
The number of rows.
|
|
1136
|
+
|
|
1137
|
+
Raises:
|
|
1138
|
+
InvalidRequestQuery: See ``refusing_invalid_values()``.
|
|
1139
|
+
"""
|
|
1140
|
+
with self.refusing_invalid_values():
|
|
1141
|
+
queryset = await self.get_filtered_queryset()
|
|
1142
|
+
return await queryset.count()
|
|
1143
|
+
|
|
1144
|
+
async def exists(self) -> bool:
|
|
1145
|
+
"""Whether any row matches the request.
|
|
1146
|
+
|
|
1147
|
+
Returns:
|
|
1148
|
+
True when a row matches.
|
|
1149
|
+
|
|
1150
|
+
Raises:
|
|
1151
|
+
InvalidRequestQuery: See ``refusing_invalid_values()``.
|
|
1152
|
+
"""
|
|
1153
|
+
with self.refusing_invalid_values():
|
|
1154
|
+
queryset = await self.get_filtered_queryset()
|
|
1155
|
+
return await queryset.exists()
|
|
1156
|
+
|
|
1157
|
+
async def delete(self) -> int | None:
|
|
1158
|
+
"""Deletes the rows the request asks for. The request's parameters or the handler's
|
|
1159
|
+
``where()`` must filter - the access condition alone doesn't count, so a request without
|
|
1160
|
+
filters never deletes everything the user may see.
|
|
1161
|
+
|
|
1162
|
+
Returns:
|
|
1163
|
+
How many rows were deleted.
|
|
1164
|
+
|
|
1165
|
+
Raises:
|
|
1166
|
+
InvalidRequestQuery: Nothing filters the rows.
|
|
1167
|
+
InvalidRequestQuery: See ``refusing_invalid_values()``.
|
|
1168
|
+
"""
|
|
1169
|
+
with self.refusing_invalid_values():
|
|
1170
|
+
return await RowChanges(self).delete()
|
|
1171
|
+
|
|
1172
|
+
async def update(self, **values: Any) -> int | None:
|
|
1173
|
+
"""Updates the rows the request asks for. As with ``delete()``, the request's parameters or
|
|
1174
|
+
the handler's ``where()`` must filter; the access condition applies.
|
|
1175
|
+
|
|
1176
|
+
Args:
|
|
1177
|
+
values: The new values by field, as for ``QuerySet.update()``.
|
|
1178
|
+
|
|
1179
|
+
Returns:
|
|
1180
|
+
How many rows were updated.
|
|
1181
|
+
|
|
1182
|
+
Raises:
|
|
1183
|
+
QueryError: No value is given.
|
|
1184
|
+
InvalidRequestQuery: Nothing filters the rows; see ``refusing_invalid_values()`` - a new
|
|
1185
|
+
value its field refuses too.
|
|
1186
|
+
"""
|
|
1187
|
+
with self.refusing_invalid_values():
|
|
1188
|
+
return await RowChanges(self).update(values)
|
|
1189
|
+
|
|
1190
|
+
async def get_for_update(self) -> ModelType:
|
|
1191
|
+
"""The one row the request asks for, locked until the surrounding transaction ends - for a
|
|
1192
|
+
handler that changes it (``SELECT ... FOR UPDATE``; a database locking no row refuses it). Call it
|
|
1193
|
+
inside a transaction. The request's fields and
|
|
1194
|
+
include parameters don't apply: only the row itself is locked and loaded.
|
|
1195
|
+
|
|
1196
|
+
Returns:
|
|
1197
|
+
The row, after ``after_fetch()``.
|
|
1198
|
+
|
|
1199
|
+
Raises:
|
|
1200
|
+
DoesNotExist: No row matches.
|
|
1201
|
+
MultipleObjectsReturned: More than one row matches.
|
|
1202
|
+
QueryError: A filter crosses a relation to many rows on a model without a primary key.
|
|
1203
|
+
InvalidRequestQuery: See ``refusing_invalid_values()``.
|
|
1204
|
+
"""
|
|
1205
|
+
with self.refusing_invalid_values():
|
|
1206
|
+
return await RowChanges(self).get_for_update()
|
|
1207
|
+
|
|
1208
|
+
async def count_by(self, *names: str, limit: int | None = None) -> dict[str, dict[Any, int]]:
|
|
1209
|
+
"""How many of the rows the request asks for have each value of each field - for the
|
|
1210
|
+
filters of a list, which show how many rows each choice leaves.
|
|
1211
|
+
|
|
1212
|
+
Each field is counted under every filter of the request except its own
|
|
1213
|
+
(``?status=draft`` still counts every status), with the search, the handler's ``where()``
|
|
1214
|
+
and the access condition. A relation counts by the related key - a tuple for a composite
|
|
1215
|
+
key; a relation to many rows counts each row once per related row; ``None`` counts the rows
|
|
1216
|
+
without a value.
|
|
1217
|
+
|
|
1218
|
+
Args:
|
|
1219
|
+
names: The fields - fields or relations, through relations (``status``, ``author``,
|
|
1220
|
+
``tags``, ``author__profile__city``).
|
|
1221
|
+
limit: How many of the most frequent values of each field to return, None for all.
|
|
1222
|
+
|
|
1223
|
+
Returns:
|
|
1224
|
+
For each field, the count of rows by value, most frequent first.
|
|
1225
|
+
|
|
1226
|
+
Raises:
|
|
1227
|
+
FieldError: A name isn't a field or relation of the model.
|
|
1228
|
+
QueryError: ``limit`` isn't a positive int, or a filter crosses a relation to many rows
|
|
1229
|
+
on a model without a primary key.
|
|
1230
|
+
InvalidRequestQuery: See ``refusing_invalid_values()``.
|
|
1231
|
+
"""
|
|
1232
|
+
with self.refusing_invalid_values():
|
|
1233
|
+
return await ValueCounter(self).count(names, limit)
|
|
1234
|
+
|
|
1235
|
+
async def get_rows_once(self, queryset: QuerySet[ModelType], method_name: str) -> QuerySet[ModelType]:
|
|
1236
|
+
"""The rows of a queryset whose filters join a relation to many rows, each once - as the
|
|
1237
|
+
rows whose primary key the queryset selects, so no ``DISTINCT`` is needed.
|
|
1238
|
+
|
|
1239
|
+
Args:
|
|
1240
|
+
queryset: The filtered queryset.
|
|
1241
|
+
method_name: The method asking, for the error.
|
|
1242
|
+
|
|
1243
|
+
Returns:
|
|
1244
|
+
The rows, each once.
|
|
1245
|
+
|
|
1246
|
+
Raises:
|
|
1247
|
+
QueryError: The model has no primary key to tell its rows apart.
|
|
1248
|
+
"""
|
|
1249
|
+
key_paths = self.get_declaration().key_ordering_paths
|
|
1250
|
+
if not key_paths:
|
|
1251
|
+
raise QueryError(
|
|
1252
|
+
f"{type(self).__qualname__}.{method_name}() can't take a filter across a relation to many rows - "
|
|
1253
|
+
f"{queryset.model.__name__} has no primary key to tell its rows apart"
|
|
1254
|
+
)
|
|
1255
|
+
rows_queryset = await self.get_rows_queryset()
|
|
1256
|
+
return rows_queryset.filter(pk__in=StatementSelection.get_values_rows_queryset(queryset).values(*key_paths))
|
|
1257
|
+
|
|
1258
|
+
|
|
1259
|
+
Caches.register(RequestQuery)
|