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,1174 @@
|
|
|
1
|
+
"""Turns a TableInfo into an InspectedModel - the model state reconstructing the table: fields,
|
|
2
|
+
composite primary key and Meta options as real objects. The model source writer and the model
|
|
3
|
+
factory both build from it.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import json
|
|
9
|
+
from dataclasses import replace
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
from hare.ddl.constraints.exclusion_constraint import ExclusionConstraint
|
|
13
|
+
from hare.ddl.constraints.unique_constraint import UniqueConstraint
|
|
14
|
+
from hare.ddl.enums import GeneratedNamePrefix
|
|
15
|
+
from hare.ddl.generated_names import GeneratedNames
|
|
16
|
+
from hare.ddl.indexes.index import Index
|
|
17
|
+
from hare.ddl.raw_sql_term import RawSQLTerm
|
|
18
|
+
from hare.dialects.dialect_registry import DialectRegistry
|
|
19
|
+
from hare.exceptions import ConfigurationError
|
|
20
|
+
from hare.fields.enums import OnDelete
|
|
21
|
+
from hare.fields.field import Field
|
|
22
|
+
from hare.inspectdb.constants import (
|
|
23
|
+
AMBIGUOUS_REASON_SENTINEL_KWARG,
|
|
24
|
+
BASE_FIELD_SENTINEL_KWARG,
|
|
25
|
+
GENERATED_INTEGER_KEY_FIELD_PATHS,
|
|
26
|
+
JSON_FIELD_PATH,
|
|
27
|
+
)
|
|
28
|
+
from hare.inspectdb.generation.column_type_mapper import ColumnTypeMapper
|
|
29
|
+
from hare.inspectdb.generation.declarations import ModelGenerationOptions
|
|
30
|
+
from hare.inspectdb.generation.inspected_model import InspectedModel
|
|
31
|
+
from hare.inspectdb.generation.model_naming import ModelNaming
|
|
32
|
+
from hare.inspectdb.introspection.column_info import ColumnInfo
|
|
33
|
+
from hare.inspectdb.introspection.database_catalog import DatabaseCatalog
|
|
34
|
+
from hare.inspectdb.introspection.index_info import IndexInfo
|
|
35
|
+
from hare.inspectdb.introspection.inspected_field_specification import InspectedFieldSpecification
|
|
36
|
+
from hare.inspectdb.introspection.table_info import TableInfo
|
|
37
|
+
from hare.migrations.state.model_state import ModelState
|
|
38
|
+
from hare.migrations.writer.migration_writer import MigrationWriter
|
|
39
|
+
from hare.models import Model
|
|
40
|
+
from hare.models.class_building.constants import TABLE_NAME_SEPARATOR
|
|
41
|
+
from hare.models.class_building.model_field_collection import ModelFieldCollection
|
|
42
|
+
from hare.models.enums import ModelOption
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class InspectedModelBuilder:
|
|
46
|
+
"""Builds one table's ``InspectedModel`` - its model state of real field, index and constraint
|
|
47
|
+
objects - across several phases, one method per phase."""
|
|
48
|
+
|
|
49
|
+
def __init__(
|
|
50
|
+
self,
|
|
51
|
+
table: TableInfo,
|
|
52
|
+
options: ModelGenerationOptions,
|
|
53
|
+
extra_reserved_attribute_names: frozenset[str] = frozenset(),
|
|
54
|
+
) -> None:
|
|
55
|
+
"""Prepares the build.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
table: The table.
|
|
59
|
+
options: How the table is turned into a model.
|
|
60
|
+
extra_reserved_attribute_names: Attribute names the model's fields mustn't take.
|
|
61
|
+
"""
|
|
62
|
+
self.table = table
|
|
63
|
+
self.dialect = options.dialect
|
|
64
|
+
self.connection_dialect = options.connection_dialect or DialectRegistry.get_dialect(options.dialect)
|
|
65
|
+
#: The dialect's introspector - its index classes and the index names it makes up.
|
|
66
|
+
self.introspector_class = DatabaseCatalog.get_dialect_introspector_class(options.dialect)
|
|
67
|
+
self.app_label = options.app_label
|
|
68
|
+
self.foreign_key_target_overrides = options.foreign_key_target_overrides or {}
|
|
69
|
+
self.skip_many_to_many_through_tables = options.skip_many_to_many_through_tables
|
|
70
|
+
#: The many-to-many fields of through tables of the run the model gets.
|
|
71
|
+
self.many_to_many_fields = options.many_to_many_fields
|
|
72
|
+
self.class_name = options.class_name or ModelNaming.get_class_name(table.name)
|
|
73
|
+
#: The fields by attribute name, in column order.
|
|
74
|
+
self.fields: dict[str, Field[Any]] = {}
|
|
75
|
+
#: Why a field is a best-effort reconstruction, by attribute name.
|
|
76
|
+
self.todo_reasons: dict[str, str] = {}
|
|
77
|
+
#: The Meta options, and the Meta body in order - an option, or a comment line.
|
|
78
|
+
self.meta_options: dict[str, Any] = {}
|
|
79
|
+
self.meta_layout: list[ModelOption | str] = []
|
|
80
|
+
#: The attribute names of a composite primary key.
|
|
81
|
+
self.composite_pk_names: list[str] | None = None
|
|
82
|
+
# A composite key's fields aren't marked primary_key=True, and a key column that is a
|
|
83
|
+
# foreign key is renamed ("event_id" -> "event") - CompositePrimaryKey names the attributes.
|
|
84
|
+
self.field_attribute_names: dict[str, str] = {}
|
|
85
|
+
#: Attributes whose field class can't be indexed (JSONField, BinaryField, ...) - an index
|
|
86
|
+
#: or UniqueConstraint over one can't be declared on the model.
|
|
87
|
+
self.non_indexable_attribute_names: set[str] = set()
|
|
88
|
+
self.reserved_attribute_names = (
|
|
89
|
+
ModelFieldCollection.get_reserved_field_names() | extra_reserved_attribute_names
|
|
90
|
+
)
|
|
91
|
+
self.used_attribute_names: set[str] = {
|
|
92
|
+
name
|
|
93
|
+
for composite_foreign_key in table.composite_foreign_keys
|
|
94
|
+
for name in (composite_foreign_key.field_name, *composite_foreign_key.columns)
|
|
95
|
+
}
|
|
96
|
+
#: Indexes reconstructed as a composite ForeignKeyField's own default index instead of a
|
|
97
|
+
#: Meta.indexes entry.
|
|
98
|
+
self.relation_index_ids: set[int] = set()
|
|
99
|
+
#: A relation can only name a model of this same run, so a foreign key to a table of
|
|
100
|
+
#: another schema stays a plain column.
|
|
101
|
+
self.foreign_keys = {
|
|
102
|
+
column_name: foreign_key
|
|
103
|
+
for column_name, foreign_key in table.foreign_keys.items()
|
|
104
|
+
if foreign_key.target_schema in (None, table.schema)
|
|
105
|
+
}
|
|
106
|
+
self.cross_schema_foreign_keys = {
|
|
107
|
+
column_name: foreign_key
|
|
108
|
+
for column_name, foreign_key in table.foreign_keys.items()
|
|
109
|
+
if column_name not in self.foreign_keys
|
|
110
|
+
}
|
|
111
|
+
#: A single-column UNIQUE declared as a UniqueConstraint - a DEFERRABLE one (unique=True can't carry
|
|
112
|
+
#: the deferral), one under a name of its own (unique=True always gets a generated name) or one of
|
|
113
|
+
#: the single-column primary key (a key field declares no uniqueness of its own).
|
|
114
|
+
primary_key_columns = [column.name for column in table.columns if column.is_pk]
|
|
115
|
+
self.constraint_unique_column_indexes = {
|
|
116
|
+
index.columns[0]: index
|
|
117
|
+
for index in table.column_indexes
|
|
118
|
+
if index.is_unique
|
|
119
|
+
and (
|
|
120
|
+
index.deferrable
|
|
121
|
+
or index.columns == primary_key_columns
|
|
122
|
+
or not self.is_default_index_name(index.name, GeneratedNamePrefix.UNIQUE_CONSTRAINT, index.columns)
|
|
123
|
+
)
|
|
124
|
+
}
|
|
125
|
+
#: A plain single-column index under a name of its own is declared as a named Meta.indexes
|
|
126
|
+
#: entry - db_index=True always gets a generated name.
|
|
127
|
+
self.named_column_indexes = {
|
|
128
|
+
index.columns[0]: index
|
|
129
|
+
for index in table.column_indexes
|
|
130
|
+
if not index.is_unique
|
|
131
|
+
and index.columns[0] not in self.foreign_keys
|
|
132
|
+
and not self.is_default_index_name(index.name, GeneratedNamePrefix.INDEX, index.columns)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
@staticmethod
|
|
136
|
+
def has_unique_constraint_options(index: IndexInfo) -> bool:
|
|
137
|
+
"""Whether a unique index has what only a UniqueConstraint declares - a deferral, non-key
|
|
138
|
+
columns, ``NULLS NOT DISTINCT`` or ``WITHOUT OVERLAPS``."""
|
|
139
|
+
return bool(index.deferrable or index.include or index.nulls_not_distinct or index.without_overlaps)
|
|
140
|
+
|
|
141
|
+
def is_default_index_name(
|
|
142
|
+
self, name: str, prefix: GeneratedNamePrefix, column_names: list[str], name_parts: tuple[str, ...] = ()
|
|
143
|
+
) -> bool:
|
|
144
|
+
"""Whether an index's name is the one it gets without an explicit name.
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
name: The index's name in the database.
|
|
148
|
+
prefix: hare's generated-name prefix for the declaration.
|
|
149
|
+
column_names: The index's columns, or its rendered expression terms.
|
|
150
|
+
name_parts: What else hare hashes into the generated name.
|
|
151
|
+
|
|
152
|
+
Returns:
|
|
153
|
+
True for hare's generated name, or a name the database made up for an index or
|
|
154
|
+
UNIQUE constraint declared without one (``SchemaIntrospector.is_unnamed_index_name``).
|
|
155
|
+
"""
|
|
156
|
+
if self.introspector_class.is_unnamed_index_name(name, self.table.name, column_names):
|
|
157
|
+
return True
|
|
158
|
+
return name == GeneratedNames.get_index_name(prefix, self.table.name, column_names, name_parts)
|
|
159
|
+
|
|
160
|
+
def is_default_special_index_name(
|
|
161
|
+
self, index: IndexInfo, index_class: type[Index], args: list[Any], kwargs: dict[str, Any]
|
|
162
|
+
) -> bool:
|
|
163
|
+
"""Whether a Meta.indexes entry's database name is the one hare generates for it.
|
|
164
|
+
|
|
165
|
+
Args:
|
|
166
|
+
index: The introspected index.
|
|
167
|
+
index_class: The reconstructed index's class.
|
|
168
|
+
args: Its positional arguments.
|
|
169
|
+
kwargs: Its keyword arguments.
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
True when the declaration without name= gets exactly that name, or when the name it
|
|
173
|
+
would get can't be worked out.
|
|
174
|
+
"""
|
|
175
|
+
kwargs = dict(kwargs)
|
|
176
|
+
args = list(args)
|
|
177
|
+
if "fields" in kwargs:
|
|
178
|
+
kwargs["fields"] = index.get_declared_fields(list(index.columns))
|
|
179
|
+
elif index.expression_terms is None and index.has_explicit_null_placement():
|
|
180
|
+
args = index.get_ordered_key_terms(list(index.columns))
|
|
181
|
+
try:
|
|
182
|
+
declared_index = index_class(*args, **kwargs)
|
|
183
|
+
field_names = declared_index.field_names
|
|
184
|
+
except (ConfigurationError, TypeError, ValueError):
|
|
185
|
+
return True
|
|
186
|
+
prefix = GeneratedNamePrefix.UNIQUE_INDEX if declared_index.unique else GeneratedNamePrefix.INDEX
|
|
187
|
+
return self.is_default_index_name(index.name, prefix, field_names, declared_index.get_name_parts())
|
|
188
|
+
|
|
189
|
+
def is_indexed_by_leading_columns(self, column_names: list[str]) -> bool:
|
|
190
|
+
"""Whether a plain or unique index, or the composite primary key, starts with these
|
|
191
|
+
columns in any order - a ForeignKeyField over them then needs no index of its own.
|
|
192
|
+
|
|
193
|
+
Args:
|
|
194
|
+
column_names: The relation's key columns.
|
|
195
|
+
|
|
196
|
+
Returns:
|
|
197
|
+
True when such an index exists.
|
|
198
|
+
"""
|
|
199
|
+
leading_column_lists = [
|
|
200
|
+
index.columns for index in self.table.indexes if not index.is_special(unique_include_is_constraint=True)
|
|
201
|
+
]
|
|
202
|
+
if self.is_composite_pk:
|
|
203
|
+
leading_column_lists.append(self.pk_columns)
|
|
204
|
+
return any(
|
|
205
|
+
set(leading_columns[: len(column_names)]) == set(column_names) for leading_columns in leading_column_lists
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
def get_foreign_key_index_kwargs(self, column_names: list[str], has_index: bool) -> dict[str, Any]:
|
|
209
|
+
"""The ``db_index`` kwarg a ForeignKeyField over these columns needs - it's indexed by default.
|
|
210
|
+
|
|
211
|
+
Args:
|
|
212
|
+
column_names: The relation's key columns.
|
|
213
|
+
has_index: Whether the database has the relation's own index.
|
|
214
|
+
|
|
215
|
+
Returns:
|
|
216
|
+
``{"db_index": False}`` when the columns have no index at all, else nothing.
|
|
217
|
+
"""
|
|
218
|
+
if has_index or self.is_indexed_by_leading_columns(column_names):
|
|
219
|
+
return {}
|
|
220
|
+
return {"db_index": False}
|
|
221
|
+
|
|
222
|
+
@staticmethod
|
|
223
|
+
def get_field_db_default(field_path: str, db_default: Any) -> Any:
|
|
224
|
+
"""Adapts an introspected column default to the field class it is declared on.
|
|
225
|
+
|
|
226
|
+
Args:
|
|
227
|
+
field_path: Dotted path of the generated field class.
|
|
228
|
+
db_default: The introspected default.
|
|
229
|
+
|
|
230
|
+
Returns:
|
|
231
|
+
For a JSONField, a string default parsed as the JSON document it holds (kept as a
|
|
232
|
+
string it would be stored as a JSON string literal); otherwise db_default unchanged.
|
|
233
|
+
"""
|
|
234
|
+
if field_path != JSON_FIELD_PATH or not isinstance(db_default, str):
|
|
235
|
+
return db_default
|
|
236
|
+
try:
|
|
237
|
+
return json.loads(db_default)
|
|
238
|
+
except ValueError:
|
|
239
|
+
return db_default
|
|
240
|
+
|
|
241
|
+
@staticmethod
|
|
242
|
+
def construct(path: str, args: list[Any] | None = None, kwargs: dict[str, Any] | None = None) -> Any:
|
|
243
|
+
"""The object ``path(*args, **kwargs)`` builds - a field, an index, a constraint.
|
|
244
|
+
|
|
245
|
+
Args:
|
|
246
|
+
path: The dotted path of the class.
|
|
247
|
+
args: The positional arguments.
|
|
248
|
+
kwargs: The keyword arguments.
|
|
249
|
+
|
|
250
|
+
Returns:
|
|
251
|
+
The object.
|
|
252
|
+
"""
|
|
253
|
+
# A field held in an argument (an array's element) is built first.
|
|
254
|
+
return MigrationWriter.get_callable(path)(
|
|
255
|
+
*InspectedFieldSpecification.build_arguments(args or []),
|
|
256
|
+
**InspectedFieldSpecification.build_arguments(kwargs or {}),
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
def get_column_type_reason(self, path: str, field_kwargs: dict[str, Any], column: ColumnInfo) -> str | None:
|
|
260
|
+
"""Why the field a column is reconstructed as keeps another column type than the column has
|
|
261
|
+
- a type hare has no field of exactly (``real``, ``json``, an unconstrained ``numeric``), which
|
|
262
|
+
drift reports until the column is altered.
|
|
263
|
+
|
|
264
|
+
Args:
|
|
265
|
+
path: The field class's import path.
|
|
266
|
+
field_kwargs: The field's type arguments.
|
|
267
|
+
column: The column.
|
|
268
|
+
|
|
269
|
+
Returns:
|
|
270
|
+
The reason, None when the field's column type is the column's.
|
|
271
|
+
"""
|
|
272
|
+
introspector_class = DatabaseCatalog.get_dialect_introspector_class(self.dialect)
|
|
273
|
+
try:
|
|
274
|
+
field = MigrationWriter.get_callable(path)(
|
|
275
|
+
null=column.nullable, **InspectedFieldSpecification.build_arguments(field_kwargs)
|
|
276
|
+
)
|
|
277
|
+
declared_type = field.get_column_type(self.connection_dialect)
|
|
278
|
+
except (ConfigurationError, TypeError, ValueError):
|
|
279
|
+
return None
|
|
280
|
+
if declared_type is None or not introspector_class.column_types_differ(declared_type, column):
|
|
281
|
+
return None
|
|
282
|
+
return (
|
|
283
|
+
f"the column is {column.db_type!r}, the field writes {declared_type!r} - hare has no field of the "
|
|
284
|
+
"column's own type; drift reports the difference until the column is altered to the field's type"
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
def add_field(self, attribute_name: str, field: Field[Any], todo_reason: str | None) -> None:
|
|
288
|
+
"""Adds a field, with why it is a best-effort reconstruction when it is one."""
|
|
289
|
+
self.fields[attribute_name] = field
|
|
290
|
+
if todo_reason:
|
|
291
|
+
self.todo_reasons[attribute_name] = todo_reason
|
|
292
|
+
|
|
293
|
+
def add_meta_option(self, option: ModelOption, value: Any) -> None:
|
|
294
|
+
"""Adds a Meta option, after the Meta body written so far."""
|
|
295
|
+
self.meta_options[option] = value
|
|
296
|
+
self.meta_layout.append(option)
|
|
297
|
+
|
|
298
|
+
def get_foreign_key_target_reference(self, target_table: str) -> str:
|
|
299
|
+
return (
|
|
300
|
+
self.foreign_key_target_overrides.get(target_table)
|
|
301
|
+
or f"{self.app_label}.{ModelNaming.get_class_name(target_table)}"
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
def build(self) -> InspectedModel:
|
|
305
|
+
"""Builds the inspected model.
|
|
306
|
+
|
|
307
|
+
Returns:
|
|
308
|
+
The inspected model - without a state, with ``skipped_note``, when the table was
|
|
309
|
+
skipped as a ManyToManyField through table.
|
|
310
|
+
"""
|
|
311
|
+
# The default table name is the lower-cased class name, which differs from a name with
|
|
312
|
+
# underscores.
|
|
313
|
+
self.needs_table_meta = self.table.name != self.class_name.lower()
|
|
314
|
+
# A model with no explicit Meta.schema lives in the connection's default schema.
|
|
315
|
+
self.needs_schema_meta = not self.table.is_in_default_schema
|
|
316
|
+
|
|
317
|
+
if TABLE_NAME_SEPARATOR in self.table.name:
|
|
318
|
+
reason = f"the name of table {self.table.name!r} holds a dot, which no Meta.table holds"
|
|
319
|
+
return InspectedModel(
|
|
320
|
+
class_name=self.class_name,
|
|
321
|
+
table_name=self.table.name,
|
|
322
|
+
state=None,
|
|
323
|
+
skipped_note=f"# Skipped: {reason} - rename the table to declare a model for it.",
|
|
324
|
+
unmodelable_reason=reason,
|
|
325
|
+
)
|
|
326
|
+
many_to_many_through_table_note = self._check_many_to_many_through_table()
|
|
327
|
+
if many_to_many_through_table_note is not None and self.skip_many_to_many_through_tables:
|
|
328
|
+
return InspectedModel(
|
|
329
|
+
class_name=self.class_name,
|
|
330
|
+
table_name=self.table.name,
|
|
331
|
+
state=None,
|
|
332
|
+
skipped_note=many_to_many_through_table_note,
|
|
333
|
+
)
|
|
334
|
+
|
|
335
|
+
self._get_primary_key_columns()
|
|
336
|
+
self._detect_relations_needing_related_name()
|
|
337
|
+
foreign_key_columns_needing_raw_name = self._detect_foreign_key_columns_needing_raw_name()
|
|
338
|
+
composite_foreign_key_member_columns = self._track_composite_foreign_key_member_columns()
|
|
339
|
+
self._build_columns(foreign_key_columns_needing_raw_name, composite_foreign_key_member_columns)
|
|
340
|
+
for preferred_name, many_to_many_field in self.many_to_many_fields:
|
|
341
|
+
self.fields[self._allocate_attribute_name(preferred_name)] = many_to_many_field
|
|
342
|
+
self._build_composite_foreign_key_fields()
|
|
343
|
+
self._build_composite_pk()
|
|
344
|
+
self._build_meta_entries()
|
|
345
|
+
return self.get_inspected_model()
|
|
346
|
+
|
|
347
|
+
def get_inspected_model(self) -> InspectedModel:
|
|
348
|
+
"""The inspected model of the phases built.
|
|
349
|
+
|
|
350
|
+
Returns:
|
|
351
|
+
The inspected model.
|
|
352
|
+
"""
|
|
353
|
+
pk_field_name: str | tuple[str, ...]
|
|
354
|
+
options = dict(self.meta_options)
|
|
355
|
+
if self.composite_pk_names is not None:
|
|
356
|
+
pk_field_name = tuple(self.composite_pk_names)
|
|
357
|
+
if self.table.primary_key_without_overlaps:
|
|
358
|
+
# Declared by the CompositePrimaryKey, not in Meta.
|
|
359
|
+
options[ModelOption.PK_WITHOUT_OVERLAPS] = True
|
|
360
|
+
else:
|
|
361
|
+
pk_field_name = next((name for name, field in self.fields.items() if field.pk), "")
|
|
362
|
+
state = ModelState(
|
|
363
|
+
name=self.class_name,
|
|
364
|
+
app=self.app_label,
|
|
365
|
+
table=self.table.name,
|
|
366
|
+
abstract=False,
|
|
367
|
+
description=self.table.table_description or "",
|
|
368
|
+
options=options,
|
|
369
|
+
bases=(Model,),
|
|
370
|
+
pk_field_name=pk_field_name,
|
|
371
|
+
fields=dict(self.fields),
|
|
372
|
+
)
|
|
373
|
+
return InspectedModel(
|
|
374
|
+
class_name=self.class_name,
|
|
375
|
+
table_name=self.table.name,
|
|
376
|
+
state=state,
|
|
377
|
+
todo_reasons=dict(self.todo_reasons),
|
|
378
|
+
meta_layout=list(self.meta_layout),
|
|
379
|
+
)
|
|
380
|
+
|
|
381
|
+
def _check_many_to_many_through_table(self) -> str | None:
|
|
382
|
+
"""A note when the table has hare's many-to-many through table shape - every column in a
|
|
383
|
+
foreign key, two or more of them - which the many-to-many field rebuilds.
|
|
384
|
+
|
|
385
|
+
Returns:
|
|
386
|
+
The note, None for any other table.
|
|
387
|
+
"""
|
|
388
|
+
if self.table.is_many_to_many_junction_shape:
|
|
389
|
+
return (
|
|
390
|
+
f"# NOTE: table {self.table.name!r} looks like a ManyToManyField through table "
|
|
391
|
+
"(every column is a foreign key, no other columns) - skipped. Declare the M2M "
|
|
392
|
+
f"field on one of its related models with through={self.table.name!r} instead of "
|
|
393
|
+
"modeling this table directly.\n"
|
|
394
|
+
)
|
|
395
|
+
return None
|
|
396
|
+
|
|
397
|
+
def _get_primary_key_columns(self) -> None:
|
|
398
|
+
# Sorted by the constraint's own declared position, not table.columns' physical layout -
|
|
399
|
+
# a composite PK's declared column order can differ from it (see ColumnInfo.pk_position).
|
|
400
|
+
self.pk_columns = [
|
|
401
|
+
column.name
|
|
402
|
+
for column in sorted(
|
|
403
|
+
(candidate for candidate in self.table.columns if candidate.is_pk),
|
|
404
|
+
key=lambda candidate: candidate.pk_position or 0,
|
|
405
|
+
)
|
|
406
|
+
]
|
|
407
|
+
self.is_composite_pk = len(self.pk_columns) > 1
|
|
408
|
+
|
|
409
|
+
def _detect_relations_needing_related_name(self) -> None:
|
|
410
|
+
"""Two relations from this table to the same target would both get the default backward
|
|
411
|
+
relation name on that target - every relation to such a target gets an explicit
|
|
412
|
+
``related_name="<table>_<field>_set"`` instead."""
|
|
413
|
+
# A single-column FK that's also a composite PK member is rendered as a plain field.
|
|
414
|
+
relation_target_tables = [
|
|
415
|
+
foreign_key.target_table
|
|
416
|
+
for column_name, foreign_key in self.foreign_keys.items()
|
|
417
|
+
if not (column_name in self.pk_columns and self.is_composite_pk)
|
|
418
|
+
] + [cfk.target_table for cfk in self.table.composite_foreign_keys]
|
|
419
|
+
self.targets_needing_related_name = {
|
|
420
|
+
target_table for target_table in relation_target_tables if relation_target_tables.count(target_table) > 1
|
|
421
|
+
}
|
|
422
|
+
self.foreign_key_columns_needing_related_name = {
|
|
423
|
+
column_name
|
|
424
|
+
for column_name, foreign_key in self.foreign_keys.items()
|
|
425
|
+
if foreign_key.target_table in self.targets_needing_related_name
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
def _detect_foreign_key_columns_needing_raw_name(self) -> set[str]:
|
|
429
|
+
"""The foreign key columns whose name without "_id" collides with another column's - they keep
|
|
430
|
+
the raw name with source_field=.
|
|
431
|
+
"""
|
|
432
|
+
candidate_name_columns: dict[str, list[str]] = {}
|
|
433
|
+
for column in self.table.columns:
|
|
434
|
+
candidate = (
|
|
435
|
+
(column.name[:-3] if column.name.endswith("_id") else f"{column.name}_fk")
|
|
436
|
+
if column.name in self.foreign_keys
|
|
437
|
+
else column.name
|
|
438
|
+
)
|
|
439
|
+
candidate_name_columns.setdefault(candidate, []).append(column.name)
|
|
440
|
+
return {
|
|
441
|
+
column_name
|
|
442
|
+
for column_names in candidate_name_columns.values()
|
|
443
|
+
if len(column_names) > 1
|
|
444
|
+
for column_name in column_names
|
|
445
|
+
if column_name in self.foreign_keys
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
def _track_composite_foreign_key_member_columns(self) -> set[str]:
|
|
449
|
+
# A composite foreign key's columns are the relation's key columns, not fields of their own.
|
|
450
|
+
composite_foreign_key_member_columns = {
|
|
451
|
+
column_name for cfk in self.table.composite_foreign_keys for column_name in cfk.columns
|
|
452
|
+
}
|
|
453
|
+
for column_name in composite_foreign_key_member_columns:
|
|
454
|
+
self.field_attribute_names[column_name] = column_name
|
|
455
|
+
return composite_foreign_key_member_columns
|
|
456
|
+
|
|
457
|
+
def _allocate_attribute_name(self, preferred_name: str) -> str:
|
|
458
|
+
"""Picks a unique attribute name that doesn't shadow a Model attribute.
|
|
459
|
+
|
|
460
|
+
Args:
|
|
461
|
+
preferred_name: Already identifier-safe name derived from the column.
|
|
462
|
+
|
|
463
|
+
Returns:
|
|
464
|
+
preferred_name, with ``_field`` appended while it is reserved - a field name ends in no
|
|
465
|
+
``_`` - and a numeric suffix (_2, _3, ...) while it is already taken by an earlier attribute.
|
|
466
|
+
"""
|
|
467
|
+
attribute_name = preferred_name
|
|
468
|
+
while attribute_name in self.reserved_attribute_names:
|
|
469
|
+
attribute_name = f"{attribute_name}_field"
|
|
470
|
+
if attribute_name in self.used_attribute_names:
|
|
471
|
+
suffix = 2
|
|
472
|
+
numbered_name = f"{attribute_name}_{suffix}"
|
|
473
|
+
while numbered_name in self.used_attribute_names or numbered_name in self.reserved_attribute_names:
|
|
474
|
+
suffix += 1
|
|
475
|
+
numbered_name = f"{attribute_name}_{suffix}"
|
|
476
|
+
attribute_name = numbered_name
|
|
477
|
+
self.used_attribute_names.add(attribute_name)
|
|
478
|
+
return attribute_name
|
|
479
|
+
|
|
480
|
+
def _build_columns(
|
|
481
|
+
self, foreign_key_columns_needing_raw_name: set[str], composite_foreign_key_member_columns: set[str]
|
|
482
|
+
) -> None:
|
|
483
|
+
for column in self.table.columns:
|
|
484
|
+
if column.name in composite_foreign_key_member_columns:
|
|
485
|
+
continue
|
|
486
|
+
# A single-column FK that's ALSO a composite PK member can't be a ForeignKeyField -
|
|
487
|
+
# CompositePrimaryKey rejects any relation field as a component. It falls through to
|
|
488
|
+
# the plain-field path below instead, with the relation dropped and flagged.
|
|
489
|
+
if column.name in self.foreign_keys and not (column.name in self.pk_columns and self.is_composite_pk):
|
|
490
|
+
self._build_foreign_key_column(column.name, foreign_key_columns_needing_raw_name)
|
|
491
|
+
continue
|
|
492
|
+
self._build_plain_column(column.name)
|
|
493
|
+
|
|
494
|
+
def _build_foreign_key_column(self, column_name: str, foreign_key_columns_needing_raw_name: set[str]) -> None:
|
|
495
|
+
column = next(column for column in self.table.columns if column.name == column_name)
|
|
496
|
+
foreign_key = self.foreign_keys[column_name]
|
|
497
|
+
needs_source_field = False
|
|
498
|
+
if column_name in foreign_key_columns_needing_raw_name:
|
|
499
|
+
raw_foreign_key_field_name = column_name
|
|
500
|
+
needs_source_field = True
|
|
501
|
+
else:
|
|
502
|
+
raw_foreign_key_field_name = column_name[:-3] if column_name.endswith("_id") else f"{column_name}_fk"
|
|
503
|
+
foreign_key_field_name = self._allocate_attribute_name(ModelNaming.get_field_name(raw_foreign_key_field_name))
|
|
504
|
+
self.field_attribute_names[column_name] = foreign_key_field_name
|
|
505
|
+
kwargs: dict[str, Any] = {}
|
|
506
|
+
# A relation's shadow column defaults to "<attribute>_id" - any other real column name
|
|
507
|
+
# (a raw/renamed attribute, or a column without the "_id" suffix) needs source_field=.
|
|
508
|
+
if needs_source_field or f"{foreign_key_field_name}_id" != column_name:
|
|
509
|
+
kwargs["source_field"] = column_name
|
|
510
|
+
if column_name in self.foreign_key_columns_needing_related_name:
|
|
511
|
+
kwargs["related_name"] = ModelNaming.get_field_name(f"{self.table.name}_{foreign_key_field_name}_set")
|
|
512
|
+
# An FK column that is itself the table's (non-composite) primary key holds at most one row
|
|
513
|
+
# per related object - only OneToOneField accepts primary_key=True.
|
|
514
|
+
field_path = "hare.fields.relations.fields.ForeignKeyFieldInstance"
|
|
515
|
+
if column.is_pk and not self.is_composite_pk:
|
|
516
|
+
field_path = "hare.fields.relations.fields.OneToOneFieldInstance"
|
|
517
|
+
kwargs["primary_key"] = True
|
|
518
|
+
else:
|
|
519
|
+
if column.nullable:
|
|
520
|
+
kwargs["null"] = True
|
|
521
|
+
# A single-column UNIQUE FK is a one-to-one relation - the only relation field that
|
|
522
|
+
# emits the UNIQUE constraint.
|
|
523
|
+
if (
|
|
524
|
+
column.is_unique
|
|
525
|
+
and not self.is_composite_pk
|
|
526
|
+
and column_name not in self.constraint_unique_column_indexes
|
|
527
|
+
):
|
|
528
|
+
field_path = "hare.fields.relations.fields.OneToOneFieldInstance"
|
|
529
|
+
if column.has_index:
|
|
530
|
+
kwargs["db_index"] = True
|
|
531
|
+
else:
|
|
532
|
+
kwargs.update(self.get_foreign_key_index_kwargs([column_name], column.has_index))
|
|
533
|
+
if column.db_default is not None:
|
|
534
|
+
kwargs["db_default"] = column.db_default
|
|
535
|
+
if foreign_key.to_field is not None:
|
|
536
|
+
kwargs["to_field"] = foreign_key.to_field
|
|
537
|
+
on_delete, rules_todo_reason = ColumnTypeMapper.get_foreign_key_rules(
|
|
538
|
+
foreign_key.on_delete, foreign_key.on_update, foreign_key.deferral
|
|
539
|
+
)
|
|
540
|
+
on_delete, set_default_todo_reason = ColumnTypeMapper.get_on_delete_fallback(
|
|
541
|
+
on_delete, column.db_default is not None, column.nullable
|
|
542
|
+
)
|
|
543
|
+
todo_reason = "; ".join(filter(None, (set_default_todo_reason, rules_todo_reason))) or None
|
|
544
|
+
if on_delete != OnDelete.CASCADE:
|
|
545
|
+
kwargs["on_delete"] = on_delete
|
|
546
|
+
if column.description:
|
|
547
|
+
kwargs["description"] = column.description
|
|
548
|
+
field = self.construct(field_path, [self.get_foreign_key_target_reference(foreign_key.target_table)], kwargs)
|
|
549
|
+
self.add_field(foreign_key_field_name, field, todo_reason)
|
|
550
|
+
|
|
551
|
+
def _add_column_options(
|
|
552
|
+
self, kwargs: dict[str, Any], column: ColumnInfo, attribute_name: str, is_indexable: bool
|
|
553
|
+
) -> bool:
|
|
554
|
+
"""Adds the options of a field that describe its column: the column name when it differs
|
|
555
|
+
from the attribute, then ``primary_key`` for the model's single-column primary key, else
|
|
556
|
+
``null`` / ``unique`` / ``db_index`` - a unique or indexed column covered by a deferrable
|
|
557
|
+
constraint or a named index gets that instead.
|
|
558
|
+
|
|
559
|
+
Args:
|
|
560
|
+
kwargs: The field's options, added to in order.
|
|
561
|
+
column: The column.
|
|
562
|
+
attribute_name: The field's attribute name.
|
|
563
|
+
is_indexable: Whether the field's type can be indexed.
|
|
564
|
+
|
|
565
|
+
Returns:
|
|
566
|
+
Whether the column is the model's single-column primary key.
|
|
567
|
+
"""
|
|
568
|
+
if attribute_name != column.name:
|
|
569
|
+
kwargs["source_field"] = column.name
|
|
570
|
+
if column.is_pk and not self.is_composite_pk:
|
|
571
|
+
kwargs["primary_key"] = True
|
|
572
|
+
return True
|
|
573
|
+
if column.nullable:
|
|
574
|
+
kwargs["null"] = True
|
|
575
|
+
if column.is_unique and is_indexable and column.name not in self.constraint_unique_column_indexes:
|
|
576
|
+
kwargs["unique"] = True
|
|
577
|
+
if column.has_index and is_indexable and column.name not in self.named_column_indexes:
|
|
578
|
+
kwargs["db_index"] = True
|
|
579
|
+
return False
|
|
580
|
+
|
|
581
|
+
def _build_plain_column(self, column_name: str) -> None:
|
|
582
|
+
column = next(column for column in self.table.columns if column.name == column_name)
|
|
583
|
+
attribute_name = self._allocate_attribute_name(ModelNaming.get_field_name(column.name))
|
|
584
|
+
self.field_attribute_names[column.name] = attribute_name
|
|
585
|
+
path, extra_kwargs, is_ambiguous = ColumnTypeMapper.map_column_type(self.dialect, column)
|
|
586
|
+
ambiguous_reason = extra_kwargs.pop(AMBIGUOUS_REASON_SENTINEL_KWARG, None)
|
|
587
|
+
base_field = extra_kwargs.pop(BASE_FIELD_SENTINEL_KWARG, None)
|
|
588
|
+
dropped_foreign_key_reason = None
|
|
589
|
+
if column.name in self.foreign_keys and column.name in self.pk_columns and self.is_composite_pk:
|
|
590
|
+
target_reference = self.get_foreign_key_target_reference(self.foreign_keys[column.name].target_table)
|
|
591
|
+
dropped_foreign_key_reason = (
|
|
592
|
+
"this column is also a composite primary key component, and hare-orm doesn't "
|
|
593
|
+
f"support a relation field as one - the ForeignKeyField({target_reference}) "
|
|
594
|
+
"relation was dropped; add it back by hand under a different attribute name if needed"
|
|
595
|
+
)
|
|
596
|
+
elif column.name in self.cross_schema_foreign_keys:
|
|
597
|
+
foreign_key = self.cross_schema_foreign_keys[column.name]
|
|
598
|
+
dropped_foreign_key_reason = (
|
|
599
|
+
f"a foreign key to {foreign_key.target_schema}.{foreign_key.target_table}"
|
|
600
|
+
f"({foreign_key.target_column}), a table of another schema than this inspectdb run - the "
|
|
601
|
+
"relation was dropped; declare it by hand against a model of that table with "
|
|
602
|
+
f"Meta.schema = {foreign_key.target_schema!r}"
|
|
603
|
+
)
|
|
604
|
+
is_indexable = ColumnTypeMapper.is_indexable_field_path(path)
|
|
605
|
+
if not is_indexable:
|
|
606
|
+
self.non_indexable_attribute_names.add(attribute_name)
|
|
607
|
+
dropped_index_reason = None
|
|
608
|
+
if not is_indexable and not column.is_pk and (column.is_unique or column.has_index):
|
|
609
|
+
dropped_index_reason = (
|
|
610
|
+
f"the column has a {'UNIQUE' if column.is_unique else 'plain'} index in the DB, but "
|
|
611
|
+
f"{path.rsplit('.', 1)[1]} can't be indexed - dropped; add it back by hand if it matters"
|
|
612
|
+
)
|
|
613
|
+
identity_reason = None
|
|
614
|
+
if column.identity_generation is not None and column.is_pk:
|
|
615
|
+
identity_reason = (
|
|
616
|
+
f"GENERATED {column.identity_generation} AS IDENTITY primary key - hare generates a key from a "
|
|
617
|
+
"sequence default and has no identity-column DDL; drift reports the difference until the column "
|
|
618
|
+
"is altered"
|
|
619
|
+
)
|
|
620
|
+
elif column.identity_generation is not None:
|
|
621
|
+
identity_reason = (
|
|
622
|
+
f"GENERATED {column.identity_generation} AS IDENTITY column - generated=True keeps it out of "
|
|
623
|
+
"INSERT/UPDATE and reads the assigned value back, but hare has no identity-column DDL, so "
|
|
624
|
+
"never let a migration create or alter this column"
|
|
625
|
+
)
|
|
626
|
+
todo_reason = (
|
|
627
|
+
ambiguous_reason
|
|
628
|
+
or dropped_foreign_key_reason
|
|
629
|
+
or (f"couldn't confidently map DB type {column.db_type!r}" if is_ambiguous else None)
|
|
630
|
+
or dropped_index_reason
|
|
631
|
+
or identity_reason
|
|
632
|
+
or column.todo_reason
|
|
633
|
+
or (None if base_field is not None else self.get_column_type_reason(path, extra_kwargs, column))
|
|
634
|
+
)
|
|
635
|
+
|
|
636
|
+
generated_field = (
|
|
637
|
+
None
|
|
638
|
+
if column.generated_expression is None
|
|
639
|
+
else self.introspector_class.get_generated_field(column, self.field_attribute_names)
|
|
640
|
+
)
|
|
641
|
+
if generated_field is not None:
|
|
642
|
+
# A field of the dialect generating its column itself.
|
|
643
|
+
generated_field_path, generated_field_kwargs = generated_field
|
|
644
|
+
self._add_column_options(generated_field_kwargs, column, attribute_name, is_indexable)
|
|
645
|
+
if column.description:
|
|
646
|
+
generated_field_kwargs["description"] = column.description
|
|
647
|
+
self.add_field(
|
|
648
|
+
attribute_name, self.construct(generated_field_path, kwargs=generated_field_kwargs), todo_reason
|
|
649
|
+
)
|
|
650
|
+
return
|
|
651
|
+
if column.generated_expression is not None:
|
|
652
|
+
# null/unique/db_index/description/source_field belong to the OUTER GeneratedField;
|
|
653
|
+
# only the type-shape kwargs belong on its nested output_field=. db_default is never
|
|
654
|
+
# set - a DB-level DEFAULT alongside GENERATED is rejected by both dialects.
|
|
655
|
+
kwargs: dict[str, Any] = {"expression": RawSQLTerm(column.generated_expression)}
|
|
656
|
+
if not column.generated_stored:
|
|
657
|
+
kwargs["stored"] = False
|
|
658
|
+
self._add_column_options(kwargs, column, attribute_name, is_indexable)
|
|
659
|
+
if column.description:
|
|
660
|
+
kwargs["description"] = column.description
|
|
661
|
+
kwargs["output_field"] = self.construct(path, kwargs=extra_kwargs)
|
|
662
|
+
self.add_field(
|
|
663
|
+
attribute_name,
|
|
664
|
+
self.construct("hare.fields.generated_field.GeneratedField", kwargs=kwargs),
|
|
665
|
+
todo_reason,
|
|
666
|
+
)
|
|
667
|
+
return
|
|
668
|
+
|
|
669
|
+
kwargs = dict(extra_kwargs)
|
|
670
|
+
is_primary_key = self._add_column_options(kwargs, column, attribute_name, is_indexable)
|
|
671
|
+
if not is_primary_key and identity_reason is not None:
|
|
672
|
+
kwargs["generated"] = True
|
|
673
|
+
if is_primary_key and not column.generates_key and path in GENERATED_INTEGER_KEY_FIELD_PATHS:
|
|
674
|
+
# An integer key field is generated by default - this column gets no value of the database.
|
|
675
|
+
kwargs["generated"] = False
|
|
676
|
+
# A primary key column can carry its own DB-level DEFAULT (e.g. a UUID PK with DEFAULT
|
|
677
|
+
# gen_random_uuid()) - applied regardless of is_pk.
|
|
678
|
+
if column.db_default is not None:
|
|
679
|
+
kwargs["db_default"] = InspectedModelBuilder.get_field_db_default(path, column.db_default)
|
|
680
|
+
if column.description:
|
|
681
|
+
kwargs["description"] = column.description
|
|
682
|
+
if base_field is not None:
|
|
683
|
+
base_field_path, base_field_kwargs = base_field
|
|
684
|
+
kwargs["base_field"] = self.construct(base_field_path, kwargs=base_field_kwargs)
|
|
685
|
+
self.add_field(attribute_name, self.construct(path, kwargs=kwargs), todo_reason)
|
|
686
|
+
|
|
687
|
+
def _build_composite_foreign_key_fields(self) -> None:
|
|
688
|
+
columns_by_name = {column.name: column for column in self.table.columns}
|
|
689
|
+
for cfk in self.table.composite_foreign_keys:
|
|
690
|
+
kwargs: dict[str, Any] = {}
|
|
691
|
+
# null=/unique=/db_index= apply uniformly to every shadow column of a composite
|
|
692
|
+
# relation - null=True here if ANY member column is nullable (the permissive direction).
|
|
693
|
+
nullable = any(columns_by_name[column_name].nullable for column_name in cfk.columns)
|
|
694
|
+
if nullable:
|
|
695
|
+
kwargs["null"] = True
|
|
696
|
+
# One db_default is copied onto every shadow column of a composite relation, so it can
|
|
697
|
+
# only stand for the members' own DEFAULTs when they all carry the same one.
|
|
698
|
+
column_defaults = [columns_by_name[column_name].db_default for column_name in cfk.columns]
|
|
699
|
+
shared_db_default = column_defaults[0] if len(set(map(repr, column_defaults))) == 1 else None
|
|
700
|
+
if cfk.on_delete == OnDelete.SET_DEFAULT and shared_db_default is not None:
|
|
701
|
+
kwargs["db_default"] = shared_db_default
|
|
702
|
+
# The relation's description is written onto each of its columns.
|
|
703
|
+
column_descriptions = {columns_by_name[column_name].description for column_name in cfk.columns}
|
|
704
|
+
if len(column_descriptions) == 1 and (shared_description := column_descriptions.pop()):
|
|
705
|
+
kwargs["description"] = shared_description
|
|
706
|
+
relation_index = next(
|
|
707
|
+
(
|
|
708
|
+
index
|
|
709
|
+
for index in self.table.indexes
|
|
710
|
+
if not index.is_unique
|
|
711
|
+
and not index.is_special(unique_include_is_constraint=True)
|
|
712
|
+
and index.columns == list(cfk.columns)
|
|
713
|
+
# A descending index, or one named otherwise than the relation names its index, is
|
|
714
|
+
# one of its own, not the relation's.
|
|
715
|
+
and not index.has_descending_key()
|
|
716
|
+
and self.is_default_index_name(index.name, GeneratedNamePrefix.INDEX, index.columns)
|
|
717
|
+
),
|
|
718
|
+
None,
|
|
719
|
+
)
|
|
720
|
+
if relation_index is not None:
|
|
721
|
+
self.relation_index_ids.add(id(relation_index))
|
|
722
|
+
# A plain UNIQUE over exactly the key columns is a one-to-one relation - the only
|
|
723
|
+
# relation field that emits that constraint, so it isn't declared again in Meta.
|
|
724
|
+
relation_unique_index = next(
|
|
725
|
+
(
|
|
726
|
+
index
|
|
727
|
+
for index in self.table.indexes
|
|
728
|
+
if index.is_unique
|
|
729
|
+
and not index.deferrable
|
|
730
|
+
and not index.condition_sql
|
|
731
|
+
and not index.is_special(unique_include_is_constraint=True)
|
|
732
|
+
# In the order of the key - another order is a constraint of its own.
|
|
733
|
+
and index.columns == list(cfk.columns)
|
|
734
|
+
and not index.has_descending_key()
|
|
735
|
+
),
|
|
736
|
+
None,
|
|
737
|
+
)
|
|
738
|
+
field_path = "hare.fields.relations.fields.ForeignKeyFieldInstance"
|
|
739
|
+
if relation_unique_index is not None and not self.is_composite_pk:
|
|
740
|
+
self.relation_index_ids.add(id(relation_unique_index))
|
|
741
|
+
field_path = "hare.fields.relations.fields.OneToOneFieldInstance"
|
|
742
|
+
if relation_index is not None:
|
|
743
|
+
kwargs["db_index"] = True
|
|
744
|
+
else:
|
|
745
|
+
kwargs.update(self.get_foreign_key_index_kwargs(list(cfk.columns), relation_index is not None))
|
|
746
|
+
on_delete, rules_todo_reason = ColumnTypeMapper.get_foreign_key_rules(
|
|
747
|
+
cfk.on_delete, cfk.on_update, cfk.deferral
|
|
748
|
+
)
|
|
749
|
+
on_delete, set_default_todo_reason = ColumnTypeMapper.get_on_delete_fallback(
|
|
750
|
+
on_delete, shared_db_default is not None, nullable
|
|
751
|
+
)
|
|
752
|
+
todo_reason = "; ".join(filter(None, (set_default_todo_reason, rules_todo_reason))) or None
|
|
753
|
+
if on_delete != OnDelete.CASCADE:
|
|
754
|
+
kwargs["on_delete"] = on_delete
|
|
755
|
+
if cfk.target_table in self.targets_needing_related_name:
|
|
756
|
+
kwargs["related_name"] = ModelNaming.get_field_name(f"{self.table.name}_{cfk.field_name}_set")
|
|
757
|
+
field = self.construct(field_path, [self.get_foreign_key_target_reference(cfk.target_table)], kwargs)
|
|
758
|
+
self.add_field(cfk.field_name, field, todo_reason)
|
|
759
|
+
|
|
760
|
+
def get_index_field_names_by_column(self) -> dict[str, str]:
|
|
761
|
+
"""The field name of each column an index or a unique constraint lists - a composite
|
|
762
|
+
relation's columns named by the relation.
|
|
763
|
+
|
|
764
|
+
Returns:
|
|
765
|
+
The names, by column.
|
|
766
|
+
"""
|
|
767
|
+
field_names_by_column = dict(self.field_attribute_names)
|
|
768
|
+
for composite_foreign_key in self.table.composite_foreign_keys:
|
|
769
|
+
# The relation's columns in the order of its key.
|
|
770
|
+
for column_name in composite_foreign_key.columns:
|
|
771
|
+
field_names_by_column.pop(column_name, None)
|
|
772
|
+
for column_name in composite_foreign_key.columns:
|
|
773
|
+
field_names_by_column[column_name] = composite_foreign_key.field_name
|
|
774
|
+
return field_names_by_column
|
|
775
|
+
|
|
776
|
+
def get_index_field_names(self, index: IndexInfo) -> list[str]:
|
|
777
|
+
"""The field names an index or a unique constraint lists, in their order and without their
|
|
778
|
+
key orders - a composite relation's columns named once.
|
|
779
|
+
|
|
780
|
+
Args:
|
|
781
|
+
index: The index.
|
|
782
|
+
|
|
783
|
+
Returns:
|
|
784
|
+
The names.
|
|
785
|
+
"""
|
|
786
|
+
return [
|
|
787
|
+
field_name.removeprefix("-")
|
|
788
|
+
for field_name in index.get_declared_relation_fields(self.get_index_field_names_by_column())
|
|
789
|
+
]
|
|
790
|
+
|
|
791
|
+
def _build_composite_pk(self) -> None:
|
|
792
|
+
if not self.is_composite_pk:
|
|
793
|
+
return
|
|
794
|
+
self.composite_pk_names = [self.field_attribute_names[column_name] for column_name in self.pk_columns]
|
|
795
|
+
|
|
796
|
+
def _get_unique_constraint(self, index: IndexInfo) -> UniqueConstraint:
|
|
797
|
+
"""Reconstructs a unique index as a UniqueConstraint - named when its database name isn't
|
|
798
|
+
the generated one, and carrying its predicate and deferral.
|
|
799
|
+
|
|
800
|
+
Args:
|
|
801
|
+
index: A plain btree unique index over real columns.
|
|
802
|
+
|
|
803
|
+
Returns:
|
|
804
|
+
The UniqueConstraint.
|
|
805
|
+
"""
|
|
806
|
+
kwargs: dict[str, Any] = {"fields": self.get_index_field_names(index)}
|
|
807
|
+
if not self.is_default_index_name(index.name, GeneratedNamePrefix.UNIQUE_CONSTRAINT, index.columns):
|
|
808
|
+
kwargs["name"] = index.name
|
|
809
|
+
if index.condition_sql:
|
|
810
|
+
kwargs["condition"] = RawSQLTerm(index.condition_sql)
|
|
811
|
+
if index.deferrable:
|
|
812
|
+
kwargs["deferrable"] = True
|
|
813
|
+
if index.initially_deferred:
|
|
814
|
+
kwargs["initially_deferred"] = True
|
|
815
|
+
if index.include:
|
|
816
|
+
kwargs["include"] = [
|
|
817
|
+
self.field_attribute_names.get(column_name, column_name) for column_name in index.include
|
|
818
|
+
]
|
|
819
|
+
if index.nulls_not_distinct:
|
|
820
|
+
kwargs["nulls_distinct"] = False
|
|
821
|
+
if index.without_overlaps:
|
|
822
|
+
kwargs["without_overlaps"] = True
|
|
823
|
+
return UniqueConstraint(**kwargs)
|
|
824
|
+
|
|
825
|
+
@staticmethod
|
|
826
|
+
def is_partial_unique_constraint(index: IndexInfo) -> bool:
|
|
827
|
+
"""Whether an index is a partial unique btree index over plain columns - the shape a
|
|
828
|
+
UniqueConstraint(condition=...) creates."""
|
|
829
|
+
return bool(
|
|
830
|
+
index.is_unique
|
|
831
|
+
and index.condition_sql
|
|
832
|
+
and not index.index_type
|
|
833
|
+
and not index.opclasses
|
|
834
|
+
and index.expression_terms is None
|
|
835
|
+
)
|
|
836
|
+
|
|
837
|
+
def _get_special_index(self, index: IndexInfo) -> Index:
|
|
838
|
+
"""Reconstructs an index with an opclass, access method, predicate or expression term.
|
|
839
|
+
|
|
840
|
+
Args:
|
|
841
|
+
index: The introspected index.
|
|
842
|
+
|
|
843
|
+
Returns:
|
|
844
|
+
The Index, PartialIndex or access-method subclass.
|
|
845
|
+
"""
|
|
846
|
+
index_class, index_args, index_kwargs = index.get_index_declaration(
|
|
847
|
+
self.introspector_class.INDEX_CLASSES_BY_TYPE, self.get_index_field_names_by_column(), as_key_terms=False
|
|
848
|
+
)
|
|
849
|
+
if not self.is_default_special_index_name(index, index_class, index_args, index_kwargs):
|
|
850
|
+
index_kwargs["name"] = index.name
|
|
851
|
+
return index_class(*index_args, **index_kwargs)
|
|
852
|
+
|
|
853
|
+
def _build_meta_entries(self) -> None:
|
|
854
|
+
table = self.table
|
|
855
|
+
declarable_indexes, undeclarable_index_comments = self._get_declarable_indexes()
|
|
856
|
+
# A partial unique index under hare's generated PartialIndex(unique=True) name stays that
|
|
857
|
+
# PartialIndex; under any other name it is a UniqueConstraint(condition=...).
|
|
858
|
+
partial_unique_constraint_indexes = [
|
|
859
|
+
index
|
|
860
|
+
for index in declarable_indexes
|
|
861
|
+
if self.is_partial_unique_constraint(index) and self._get_special_index(index).name is not None
|
|
862
|
+
]
|
|
863
|
+
partial_unique_constraint_index_ids = {id(index) for index in partial_unique_constraint_indexes}
|
|
864
|
+
special_indexes = [
|
|
865
|
+
index
|
|
866
|
+
for index in declarable_indexes
|
|
867
|
+
if index.is_special(unique_include_is_constraint=True)
|
|
868
|
+
and id(index) not in partial_unique_constraint_index_ids
|
|
869
|
+
]
|
|
870
|
+
plain_indexes = [
|
|
871
|
+
index for index in declarable_indexes if not index.is_special(unique_include_is_constraint=True)
|
|
872
|
+
]
|
|
873
|
+
multi_column_plain = [index for index in plain_indexes if not index.is_unique]
|
|
874
|
+
|
|
875
|
+
self._add_table_meta_options()
|
|
876
|
+
index_calls = self._get_plain_index_calls(multi_column_plain)
|
|
877
|
+
special_index_calls, index_comments = self._get_special_index_calls(special_indexes)
|
|
878
|
+
index_calls.extend(special_index_calls)
|
|
879
|
+
unique_index_calls, unique_constraint_calls = self._get_unique_declarations(plain_indexes)
|
|
880
|
+
index_calls.extend(unique_index_calls)
|
|
881
|
+
unique_constraint_calls.extend(
|
|
882
|
+
self._get_unique_constraint(index)
|
|
883
|
+
for index in (*self.constraint_unique_column_indexes.values(), *partial_unique_constraint_indexes)
|
|
884
|
+
)
|
|
885
|
+
if index_calls:
|
|
886
|
+
self.add_meta_option(ModelOption.INDEXES, index_calls)
|
|
887
|
+
self._add_index_comments(index_comments, undeclarable_index_comments)
|
|
888
|
+
self._add_constraints(unique_constraint_calls)
|
|
889
|
+
self.meta_layout.extend(
|
|
890
|
+
f"# TODO: column {name!r} is a generated (GENERATED ALWAYS AS (...)) column, but "
|
|
891
|
+
"its expression text wasn't in a shape this could parse back out of the table's raw SQL "
|
|
892
|
+
f"({raw_sql!r}) - it's been dropped entirely; add it back by hand as a GeneratedField."
|
|
893
|
+
for name, raw_sql in table.unparsed_generated_columns
|
|
894
|
+
)
|
|
895
|
+
self._add_triggers()
|
|
896
|
+
self.meta_layout.extend(
|
|
897
|
+
f"# TODO: composite foreign key {name!r} ({', '.join(columns)}) wasn't reconstructed as "
|
|
898
|
+
"a ForeignKeyField - either it doesn't reference the target's whole primary key, or its "
|
|
899
|
+
'columns aren\'t named "<field>_<target key column>", the only names a composite relation '
|
|
900
|
+
"declares. The member columns are plain fields above; to declare the relation, rename the "
|
|
901
|
+
"columns so (a RunSQL migration) and replace them with the ForeignKeyField."
|
|
902
|
+
for name, columns in table.unparsed_foreign_keys
|
|
903
|
+
)
|
|
904
|
+
|
|
905
|
+
def _get_declarable_indexes(self) -> tuple[list[IndexInfo], list[str]]:
|
|
906
|
+
"""The table's indexes a model can declare - those of a relation left out - and a comment
|
|
907
|
+
on each one covering a field type that can't be indexed.
|
|
908
|
+
|
|
909
|
+
Returns:
|
|
910
|
+
The indexes, and the comments.
|
|
911
|
+
"""
|
|
912
|
+
table = self.table
|
|
913
|
+
undeclarable_index_comments = []
|
|
914
|
+
declarable_indexes = []
|
|
915
|
+
for index in table.indexes:
|
|
916
|
+
if id(index) in self.relation_index_ids:
|
|
917
|
+
continue
|
|
918
|
+
# Field.indexable only restricts a plain btree index.
|
|
919
|
+
non_indexable_names = [
|
|
920
|
+
self.field_attribute_names[column_name]
|
|
921
|
+
for column_name in index.columns
|
|
922
|
+
if not index.index_type
|
|
923
|
+
and self.field_attribute_names.get(column_name) in self.non_indexable_attribute_names
|
|
924
|
+
]
|
|
925
|
+
if non_indexable_names:
|
|
926
|
+
undeclarable_index_comments.append(
|
|
927
|
+
f"# TODO: {'unique ' if index.is_unique else ''}index {index.name or index.columns!r} wasn't "
|
|
928
|
+
f"reconstructed - it covers {', '.join(non_indexable_names)}, whose field type can't be "
|
|
929
|
+
"indexed. Add it back by hand if it matters."
|
|
930
|
+
)
|
|
931
|
+
else:
|
|
932
|
+
declarable_indexes.append(index)
|
|
933
|
+
return declarable_indexes, undeclarable_index_comments
|
|
934
|
+
|
|
935
|
+
def _add_table_meta_options(self) -> None:
|
|
936
|
+
"""Adds the Meta options of the table itself - its name, schema, description, options, and
|
|
937
|
+
no primary key for a table without one."""
|
|
938
|
+
table = self.table
|
|
939
|
+
if self.needs_table_meta:
|
|
940
|
+
self.add_meta_option(ModelOption.TABLE, table.name)
|
|
941
|
+
if not self.pk_columns:
|
|
942
|
+
# No primary key - a model without one, so
|
|
943
|
+
# the metaclass adds no "id" the table doesn't have.
|
|
944
|
+
self.add_meta_option(ModelOption.PRIMARY_KEY, None)
|
|
945
|
+
if self.needs_schema_meta:
|
|
946
|
+
self.add_meta_option(ModelOption.SCHEMA, table.schema)
|
|
947
|
+
if table.table_description:
|
|
948
|
+
self.add_meta_option(ModelOption.TABLE_DESCRIPTION, table.table_description)
|
|
949
|
+
if table.table_options is not None:
|
|
950
|
+
self.add_meta_option(
|
|
951
|
+
ModelOption.TABLE_OPTIONS, [table.table_options.with_field_names(self.field_attribute_names)]
|
|
952
|
+
)
|
|
953
|
+
if table.row_level_security is not None:
|
|
954
|
+
self.add_meta_option(ModelOption.ROW_LEVEL_SECURITY, table.row_level_security)
|
|
955
|
+
self._add_security_meta_options()
|
|
956
|
+
|
|
957
|
+
def _add_security_meta_options(self) -> None:
|
|
958
|
+
"""Adds the sequences a column of the table owns, its policies and its grants - each column
|
|
959
|
+
named by its field."""
|
|
960
|
+
table = self.table
|
|
961
|
+
if table.sequences:
|
|
962
|
+
self.add_meta_option(
|
|
963
|
+
ModelOption.SEQUENCES,
|
|
964
|
+
[
|
|
965
|
+
replace(sequence, owned_by=self.field_attribute_names.get(sequence.owned_by, sequence.owned_by))
|
|
966
|
+
if sequence.owned_by is not None
|
|
967
|
+
else sequence
|
|
968
|
+
for sequence in table.sequences
|
|
969
|
+
],
|
|
970
|
+
)
|
|
971
|
+
if table.policies:
|
|
972
|
+
self.add_meta_option(ModelOption.POLICIES, list(table.policies))
|
|
973
|
+
if table.grants:
|
|
974
|
+
self.add_meta_option(
|
|
975
|
+
ModelOption.GRANTS,
|
|
976
|
+
[
|
|
977
|
+
replace(
|
|
978
|
+
grant,
|
|
979
|
+
columns=tuple(self.field_attribute_names.get(column, column) for column in grant.columns),
|
|
980
|
+
)
|
|
981
|
+
for grant in table.grants
|
|
982
|
+
],
|
|
983
|
+
)
|
|
984
|
+
self.meta_layout.extend(f"# TODO: {note} - grant it with a RunSQL migration" for note in table.unparsed_grants)
|
|
985
|
+
|
|
986
|
+
def _get_plain_index_calls(self, multi_column_plain: list[IndexInfo]) -> list[Index]:
|
|
987
|
+
"""The ``Index`` of each plain non-unique index over several columns, and of each named index
|
|
988
|
+
of one column.
|
|
989
|
+
|
|
990
|
+
Args:
|
|
991
|
+
multi_column_plain: The plain non-unique indexes.
|
|
992
|
+
|
|
993
|
+
Returns:
|
|
994
|
+
The indexes.
|
|
995
|
+
"""
|
|
996
|
+
index_calls: list[Index] = []
|
|
997
|
+
for index in multi_column_plain:
|
|
998
|
+
declared_fields = index.get_declared_relation_fields(self.get_index_field_names_by_column())
|
|
999
|
+
index_kwargs: dict[str, Any] = {"fields": declared_fields}
|
|
1000
|
+
name_parts = Index(fields=declared_fields).get_name_parts()
|
|
1001
|
+
if not self.is_default_index_name(index.name, GeneratedNamePrefix.INDEX, index.columns, name_parts):
|
|
1002
|
+
index_kwargs["name"] = index.name
|
|
1003
|
+
index_calls.append(Index(**index_kwargs))
|
|
1004
|
+
for column_name, index in self.named_column_indexes.items():
|
|
1005
|
+
if self.field_attribute_names.get(column_name) in self.non_indexable_attribute_names:
|
|
1006
|
+
continue
|
|
1007
|
+
index_calls.append(Index(fields=[self.field_attribute_names[column_name]], name=index.name))
|
|
1008
|
+
return index_calls
|
|
1009
|
+
|
|
1010
|
+
def _get_special_index_calls(self, special_indexes: list[IndexInfo]) -> tuple[list[Index], list[str]]:
|
|
1011
|
+
"""The index of each index of another type or with options, with a note on what its
|
|
1012
|
+
declaration can't carry.
|
|
1013
|
+
|
|
1014
|
+
Args:
|
|
1015
|
+
special_indexes: The indexes.
|
|
1016
|
+
|
|
1017
|
+
Returns:
|
|
1018
|
+
The indexes, and the notes.
|
|
1019
|
+
"""
|
|
1020
|
+
index_calls: list[Index] = []
|
|
1021
|
+
index_comments: list[str] = []
|
|
1022
|
+
for index in special_indexes:
|
|
1023
|
+
index_calls.append(self._get_special_index(index))
|
|
1024
|
+
index_label = ", ".join(index.expression_terms or index.columns)
|
|
1025
|
+
if index.is_unique and index.index_type in self.introspector_class.INDEX_CLASSES_BY_TYPE:
|
|
1026
|
+
index_comments.append(
|
|
1027
|
+
f"# NOTE: {index_label} was a UNIQUE index in the DB - Index()/its "
|
|
1028
|
+
"subclasses can't express uniqueness combined with a non-btree access method, "
|
|
1029
|
+
"reconstructed here as non-unique; add the real constraint back by hand if it matters."
|
|
1030
|
+
)
|
|
1031
|
+
if index.index_type in self.introspector_class.TUNED_INDEX_TYPES and not index.storage_parameters:
|
|
1032
|
+
index_comments.append(
|
|
1033
|
+
f"# NOTE: {index_label}'s real tuning parameters (m/ef_construction/lists) "
|
|
1034
|
+
"weren't reported by the database - reconstructed with this index type's own "
|
|
1035
|
+
"defaults; verify/adjust them by hand if the original was tuned differently."
|
|
1036
|
+
)
|
|
1037
|
+
|
|
1038
|
+
return index_calls, index_comments
|
|
1039
|
+
|
|
1040
|
+
def _get_unique_declarations(self, plain_indexes: list[IndexInfo]) -> tuple[list[Index], list[UniqueConstraint]]:
|
|
1041
|
+
"""What each plain unique index stands for: an ``Index(unique=True)``, a named
|
|
1042
|
+
``UniqueConstraint``, or (under the generated name) an unnamed one.
|
|
1043
|
+
|
|
1044
|
+
Args:
|
|
1045
|
+
plain_indexes: The plain indexes, unique or not.
|
|
1046
|
+
|
|
1047
|
+
Returns:
|
|
1048
|
+
The unique indexes, and the unique constraints.
|
|
1049
|
+
"""
|
|
1050
|
+
index_calls: list[Index] = []
|
|
1051
|
+
# A plain unique index stands for the declaration whose name it has: an Index(unique=True),
|
|
1052
|
+
# a named UniqueConstraint, or (under the generated name) an unnamed one.
|
|
1053
|
+
unique_constraint_calls: list[UniqueConstraint] = []
|
|
1054
|
+
unnamed_unique_field_sets: list[tuple[str, ...]] = []
|
|
1055
|
+
for index in plain_indexes:
|
|
1056
|
+
if not index.is_unique:
|
|
1057
|
+
continue
|
|
1058
|
+
attribute_names = self.get_index_field_names(index)
|
|
1059
|
+
declared_fields = index.get_declared_relation_fields(self.get_index_field_names_by_column())
|
|
1060
|
+
if declared_fields != attribute_names:
|
|
1061
|
+
# A descending key - only an Index(unique=True) declares one.
|
|
1062
|
+
index_kwargs: dict[str, Any] = {"fields": declared_fields, "unique": True}
|
|
1063
|
+
name_parts = Index(fields=declared_fields).get_name_parts()
|
|
1064
|
+
if not self.is_default_index_name(
|
|
1065
|
+
index.name, GeneratedNamePrefix.UNIQUE_INDEX, index.columns, name_parts
|
|
1066
|
+
):
|
|
1067
|
+
index_kwargs["name"] = index.name
|
|
1068
|
+
index_calls.append(Index(**index_kwargs))
|
|
1069
|
+
continue
|
|
1070
|
+
has_constraint_options = self.has_unique_constraint_options(index)
|
|
1071
|
+
if has_constraint_options or not self.is_default_index_name(
|
|
1072
|
+
index.name, GeneratedNamePrefix.UNIQUE_CONSTRAINT, index.columns
|
|
1073
|
+
):
|
|
1074
|
+
if not has_constraint_options and self.is_default_index_name(
|
|
1075
|
+
index.name, GeneratedNamePrefix.UNIQUE_INDEX, index.columns
|
|
1076
|
+
):
|
|
1077
|
+
index_calls.append(Index(fields=attribute_names, unique=True))
|
|
1078
|
+
else:
|
|
1079
|
+
unique_constraint_calls.append(self._get_unique_constraint(index))
|
|
1080
|
+
continue
|
|
1081
|
+
# An unnamed constraint carries no name of its own, so two physical unique indexes
|
|
1082
|
+
# over the same column set are always redundant.
|
|
1083
|
+
if tuple(attribute_names) not in unnamed_unique_field_sets:
|
|
1084
|
+
unnamed_unique_field_sets.append(tuple(attribute_names))
|
|
1085
|
+
unique_constraint_calls.append(UniqueConstraint(fields=tuple(attribute_names)))
|
|
1086
|
+
return index_calls, unique_constraint_calls
|
|
1087
|
+
|
|
1088
|
+
def _add_index_comments(self, index_comments: list[str], undeclarable_index_comments: list[str]) -> None:
|
|
1089
|
+
"""Adds the comments on the indexes - what their declarations can't carry, and those not
|
|
1090
|
+
reconstructed.
|
|
1091
|
+
|
|
1092
|
+
Args:
|
|
1093
|
+
index_comments: The notes on the special indexes.
|
|
1094
|
+
undeclarable_index_comments: The comments on the indexes of a field type that can't be
|
|
1095
|
+
indexed.
|
|
1096
|
+
"""
|
|
1097
|
+
table = self.table
|
|
1098
|
+
self.meta_layout.extend(index_comments)
|
|
1099
|
+
self.meta_layout.extend(undeclarable_index_comments)
|
|
1100
|
+
self.meta_layout.extend(
|
|
1101
|
+
f"# TODO: index {index.name or index.columns!r} has {', '.join(index.unrepresentable_properties)} in "
|
|
1102
|
+
"the database, which no hare index or constraint can declare - reconstructed without it. Keep it "
|
|
1103
|
+
"with a RunSQL migration if it matters."
|
|
1104
|
+
for index in (*table.column_indexes, *table.indexes)
|
|
1105
|
+
if index.unrepresentable_properties
|
|
1106
|
+
)
|
|
1107
|
+
self.meta_layout.extend(
|
|
1108
|
+
f"# TODO: index {name!r} wasn't reconstructed ({raw_def!r}) - an expression term carries "
|
|
1109
|
+
"something Index(*expressions)/its subclasses can't represent (an operator class, sort order "
|
|
1110
|
+
"or collation next to an expression, or a definition that couldn't be parsed). Add it back by hand."
|
|
1111
|
+
for name, raw_def in table.unparsed_indexes
|
|
1112
|
+
)
|
|
1113
|
+
|
|
1114
|
+
def _add_constraints(self, unique_constraint_calls: list[UniqueConstraint]) -> None:
|
|
1115
|
+
"""Adds ``Meta.constraints`` - the unique, exclusion and CHECK constraints - and the comments
|
|
1116
|
+
on those not reconstructed.
|
|
1117
|
+
|
|
1118
|
+
Args:
|
|
1119
|
+
unique_constraint_calls: The unique constraints.
|
|
1120
|
+
"""
|
|
1121
|
+
table = self.table
|
|
1122
|
+
# Every constraint type shares ONE Meta.constraints list - separate assignments would
|
|
1123
|
+
# silently shadow each other.
|
|
1124
|
+
constraint_calls: list[Any] = list(unique_constraint_calls)
|
|
1125
|
+
for constraint in table.exclusion_constraints:
|
|
1126
|
+
renamed_constraint = ExclusionConstraint(
|
|
1127
|
+
name=constraint.name,
|
|
1128
|
+
expressions=tuple(
|
|
1129
|
+
(
|
|
1130
|
+
self.field_attribute_names.get(field_name, field_name)
|
|
1131
|
+
if isinstance(field_name, str)
|
|
1132
|
+
else field_name,
|
|
1133
|
+
operator,
|
|
1134
|
+
)
|
|
1135
|
+
for field_name, operator in constraint.expressions
|
|
1136
|
+
),
|
|
1137
|
+
using=constraint.using,
|
|
1138
|
+
condition=constraint.condition,
|
|
1139
|
+
include=tuple(
|
|
1140
|
+
self.field_attribute_names.get(column_name, column_name) for column_name in constraint.include
|
|
1141
|
+
),
|
|
1142
|
+
deferrable=constraint.deferrable,
|
|
1143
|
+
initially_deferred=constraint.initially_deferred,
|
|
1144
|
+
)
|
|
1145
|
+
constraint_calls.append(renamed_constraint)
|
|
1146
|
+
constraint_calls.extend(table.check_constraints)
|
|
1147
|
+
if constraint_calls:
|
|
1148
|
+
self.add_meta_option(ModelOption.CONSTRAINTS, constraint_calls)
|
|
1149
|
+
self.meta_layout.extend(
|
|
1150
|
+
f"# TODO: exclusion constraint {name!r} wasn't in a shape ExclusionConstraint(...) "
|
|
1151
|
+
f"could reconstruct ({raw_def!r}) - add it back by hand."
|
|
1152
|
+
for name, raw_def in table.unparsed_exclusion_constraints
|
|
1153
|
+
)
|
|
1154
|
+
self.meta_layout.extend(
|
|
1155
|
+
f"# TODO: CHECK constraint {name!r} is not validated in the database - the existing rows "
|
|
1156
|
+
"haven't been checked against it; a ValidateConstraint migration checks them."
|
|
1157
|
+
for name in table.not_valid_constraint_names
|
|
1158
|
+
)
|
|
1159
|
+
self.meta_layout.extend(
|
|
1160
|
+
f"# TODO: CHECK constraint {name!r} wasn't in a shape CheckConstraint(...) could "
|
|
1161
|
+
f"reconstruct ({raw_def!r}) - add it back by hand."
|
|
1162
|
+
for name, raw_def in table.unparsed_check_constraints
|
|
1163
|
+
)
|
|
1164
|
+
|
|
1165
|
+
def _add_triggers(self) -> None:
|
|
1166
|
+
"""Adds ``Meta.triggers`` and the comments on the triggers not reconstructed."""
|
|
1167
|
+
table = self.table
|
|
1168
|
+
if table.triggers:
|
|
1169
|
+
self.add_meta_option(ModelOption.TRIGGERS, list(table.triggers))
|
|
1170
|
+
self.meta_layout.extend(
|
|
1171
|
+
f"# TODO: trigger {name!r} wasn't in a shape Trigger(...) could reconstruct "
|
|
1172
|
+
f"({raw_def!r}) - add it back by hand."
|
|
1173
|
+
for name, raw_def in table.unparsed_triggers
|
|
1174
|
+
)
|