plain.postgres 0.108.0__tar.gz → 0.108.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/PKG-INFO +1 -1
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/CHANGELOG.md +11 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/connection.py +13 -1
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/otel.py +30 -19
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/pyproject.toml +1 -1
- plain_postgres-0.108.1/tests/conftest.py +26 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_connection_pool.py +0 -14
- plain_postgres-0.108.1/tests/internal/test_connection_self_heal.py +131 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_otel_metrics.py +29 -0
- plain_postgres-0.108.0/tests/conftest.py +0 -11
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/.gitignore +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/CLAUDE.md +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/LICENSE +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/README.md +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/README.md +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/__init__.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/adapters.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/agents/.claude/rules/plain-postgres.md +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/agents/.claude/skills/plain-postgres-doctor/SKILL.md +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/aggregates.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/base.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/cli/__init__.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/cli/converge.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/cli/core.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/cli/decorators.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/cli/diagnose.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/cli/migrations.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/cli/schema.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/cli/sync.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/config.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/constants.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/constraints.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/convergence/__init__.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/convergence/analysis.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/convergence/fixes.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/convergence/planning.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/database_url.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/db.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/ddl.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/default_settings.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/deletion.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/dialect.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/entrypoints.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/enums.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/exceptions.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/expressions.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/fields/__init__.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/fields/base.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/fields/binary.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/fields/boolean.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/fields/duration.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/fields/encrypted.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/fields/json.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/fields/mixins.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/fields/network.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/fields/numeric.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/fields/primary_key.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/fields/related.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/fields/related_descriptors.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/fields/related_lookups.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/fields/related_managers.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/fields/reverse_descriptors.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/fields/reverse_related.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/fields/temporal.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/fields/text.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/fields/timezones.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/fields/uuid.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/forms.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/functions/__init__.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/functions/comparison.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/functions/datetime.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/functions/math.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/functions/mixins.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/functions/random.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/functions/text.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/functions/uuid.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/functions/window.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/indexes.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/introspection/__init__.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/introspection/health/__init__.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/introspection/health/checks_cumulative.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/introspection/health/checks_snapshot.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/introspection/health/checks_structural.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/introspection/health/context.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/introspection/health/helpers.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/introspection/health/ownership.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/introspection/health/runner.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/introspection/health/types.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/introspection/schema.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/lookups.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/meta.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/middleware.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/migrations/__init__.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/migrations/autodetector.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/migrations/exceptions.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/migrations/executor.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/migrations/graph.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/migrations/loader.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/migrations/migration.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/migrations/operations/__init__.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/migrations/operations/base.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/migrations/operations/fields.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/migrations/operations/models.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/migrations/operations/special.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/migrations/optimizer.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/migrations/questioner.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/migrations/recorder.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/migrations/serializer.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/migrations/state.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/migrations/utils.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/migrations/writer.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/options.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/preflight/__init__.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/preflight/database.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/preflight/indexes.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/preflight/models.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/query.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/query_utils.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/registry.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/schema.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/sources.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/sql/__init__.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/sql/compiler.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/sql/constants.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/sql/datastructures.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/sql/query.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/sql/where.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/test/__init__.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/test/database.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/test/pytest.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/transaction.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/types.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/types.pyi +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/utils.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/forms.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/migrations/0001_initial.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/migrations/0002_test_field_removed.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/migrations/0003_deleteparent_childsetnull_childsetdefault_and_more.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/migrations/0004_defaultquerysetmodel_mixintestmodel_and_more.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/migrations/0005_feature_carfeature_car_features.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/migrations/0006_secretstore.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/migrations/0007_treenode_unconstrainedchild.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/migrations/0008_setsentinelparent_diamondparenta_midparent_and_more.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/migrations/0009_circb_circa_circb_partner.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/migrations/0010_hideableitem.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/migrations/0011_defaultsexample.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/migrations/0012_iterationexample.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/migrations/0013_indexexample_constraintexample_nullabilityexample.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/migrations/0014_widget_rename_feature_tag_remove_carfeature_car_and_more.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/migrations/0015_dbdefaultsexample.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/migrations/0016_formsexample.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/migrations/0017_random_string_token.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/migrations/0018_storageparametersexample.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/migrations/__init__.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/models/__init__.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/models/constraints.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/models/defaults.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/models/delete.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/models/encrypted.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/models/forms.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/models/indexes.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/models/iteration.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/models/mixins.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/models/nullability.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/models/querysets.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/models/relationships.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/models/storage_parameters.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/models/trees.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/models/unregistered.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/urls.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/examples/views.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/settings.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/app/urls.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/conftest_convergence.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_autodetector_not_null_errors.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_autodetector_type_change.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_connection_isolation.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_connection_lifecycle.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_constraint_violation_error.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_convergence.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_convergence_constraints.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_convergence_defaults.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_convergence_fk.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_convergence_indexes.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_convergence_nullability.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_convergence_storage_parameters.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_convergence_timeouts.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_db_expression_defaults.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_diagnose.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_executor_connection_hook.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_fk_characterization.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_health.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_introspection.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_literal_default_persistence.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_management_connection.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_migration_executor.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_no_callable_defaults.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_preflight_duplicate_indexes.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_preflight_fk_composite_hint.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_preflight_fk_coverage.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_schema_normalize_type.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/internal/test_schema_timeouts.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/public/test_create_update.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/public/test_database_url.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/public/test_deferred_loading.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/public/test_delete_behaviors.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/public/test_encrypted_fields.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/public/test_exceptions.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/public/test_field_defaults.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/public/test_functions_uuid.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/public/test_integrity_error_mapping.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/public/test_iterator.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/public/test_m2m.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/public/test_manager_assignment.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/public/test_manual_pk.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/public/test_mixins.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/public/test_modelform_roundtrip.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/public/test_queryset_repr.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/public/test_random_string_field.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/public/test_raw_query.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/public/test_read_only_transactions.py +0 -0
- {plain_postgres-0.108.0 → plain_postgres-0.108.1}/tests/public/test_related.py +0 -0
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# plain-postgres changelog
|
|
2
2
|
|
|
3
|
+
## [0.108.1](https://github.com/dropseed/plain/releases/plain-postgres@0.108.1) (2026-06-09)
|
|
4
|
+
|
|
5
|
+
### What's changed
|
|
6
|
+
|
|
7
|
+
- `ensure_connection()` now detects a pooled connection the server has closed while it was held (Postgres restart, failover, idle timeout) and discards it before establishing a fresh one — logging a "Discarding dead database connection" warning — instead of repeatedly failing on the dead connection. Inside an atomic block the dead connection is intentionally left in place so the transaction's normal error handling runs, rather than silently continuing the rest of the block outside its transaction. ([9e82cb4454](https://github.com/dropseed/plain/commit/9e82cb4454))
|
|
8
|
+
- Query span instrumentation no longer pays for expensive attributes when the span is sampled out: the per-query Python stack walk (for `code.*` attributes) and the `DEBUG`-mode stringification of query parameters now only happen when the span is actually recording. The cheap connection attributes are still passed at span creation so attribute-aware samplers can see them in `should_sample()`. ([af736043b0](https://github.com/dropseed/plain/commit/af736043b0))
|
|
9
|
+
|
|
10
|
+
### Upgrade instructions
|
|
11
|
+
|
|
12
|
+
- No changes required.
|
|
13
|
+
|
|
3
14
|
## [0.108.0](https://github.com/dropseed/plain/releases/plain-postgres@0.108.0) (2026-06-09)
|
|
4
15
|
|
|
5
16
|
### What's changed
|
|
@@ -170,7 +170,19 @@ class DatabaseConnection:
|
|
|
170
170
|
self.set_autocommit(True)
|
|
171
171
|
|
|
172
172
|
def ensure_connection(self) -> None:
|
|
173
|
-
"""Guarantee that a connection to the database is established."""
|
|
173
|
+
"""Guarantee that a live connection to the database is established."""
|
|
174
|
+
if (
|
|
175
|
+
self.connection is not None
|
|
176
|
+
and self.connection.closed
|
|
177
|
+
and not self.in_atomic_block
|
|
178
|
+
):
|
|
179
|
+
# The server closed this connection while we held it (restart,
|
|
180
|
+
# failover, idle timeout) — psycopg marks it closed once an
|
|
181
|
+
# operation fails on it. Mid-atomic, swapping it would silently
|
|
182
|
+
# run the rest of the block outside its transaction — leave the
|
|
183
|
+
# dead connection for Atomic.__exit__'s error recovery instead.
|
|
184
|
+
logger.warning("Discarding dead database connection")
|
|
185
|
+
self.close()
|
|
174
186
|
if self.connection is None:
|
|
175
187
|
self.connect()
|
|
176
188
|
|
|
@@ -305,7 +305,10 @@ def db_span(
|
|
|
305
305
|
# Single settings_dict read — the property delegates to source.config.
|
|
306
306
|
cfg = db.settings_dict
|
|
307
307
|
|
|
308
|
-
#
|
|
308
|
+
# Cheap attributes are passed at span creation so attribute-aware
|
|
309
|
+
# samplers can see them in should_sample(). Expensive ones (the
|
|
310
|
+
# per-query stack walk, DEBUG params) are added after, only when the
|
|
311
|
+
# span actually records.
|
|
309
312
|
attrs: dict[str, Any] = {
|
|
310
313
|
DB_SYSTEM_NAME: DB_SYSTEM,
|
|
311
314
|
DB_NAMESPACE: cfg.get("DATABASE"),
|
|
@@ -314,8 +317,6 @@ def db_span(
|
|
|
314
317
|
DB_OPERATION_NAME: operation,
|
|
315
318
|
}
|
|
316
319
|
|
|
317
|
-
attrs.update(_get_code_attributes())
|
|
318
|
-
|
|
319
320
|
# Add collection name if detected
|
|
320
321
|
if collection_name:
|
|
321
322
|
attrs[DB_COLLECTION_NAME] = collection_name
|
|
@@ -335,31 +336,41 @@ def db_span(
|
|
|
335
336
|
attrs[SERVER_PORT] = port_int
|
|
336
337
|
attrs[NETWORK_PEER_PORT] = port_int
|
|
337
338
|
|
|
338
|
-
# Add query parameters as attributes when DEBUG is True
|
|
339
|
-
if settings.DEBUG and params is not None:
|
|
340
|
-
# Convert params to appropriate format based on type
|
|
341
|
-
if isinstance(params, dict):
|
|
342
|
-
# Dictionary params (e.g., for named placeholders)
|
|
343
|
-
for key, value in params.items():
|
|
344
|
-
attrs[f"{DB_QUERY_PARAMETER_TEMPLATE}.{key}"] = str(value)
|
|
345
|
-
elif isinstance(params, list | tuple):
|
|
346
|
-
# Sequential params (e.g., for %s or ? placeholders)
|
|
347
|
-
for i, value in enumerate(params):
|
|
348
|
-
attrs[f"{DB_QUERY_PARAMETER_TEMPLATE}.{i + 1}"] = str(value)
|
|
349
|
-
else:
|
|
350
|
-
# Single param (rare but possible)
|
|
351
|
-
attrs[f"{DB_QUERY_PARAMETER_TEMPLATE}.1"] = str(params)
|
|
352
|
-
|
|
353
339
|
with tracer.start_as_current_span(
|
|
354
340
|
span_name, kind=SpanKind.CLIENT, attributes=attrs
|
|
355
341
|
) as span:
|
|
342
|
+
if span.is_recording():
|
|
343
|
+
expensive_attrs = _get_code_attributes()
|
|
344
|
+
|
|
345
|
+
# Add query parameters as attributes when DEBUG is True
|
|
346
|
+
if settings.DEBUG and params is not None:
|
|
347
|
+
# Convert params to appropriate format based on type
|
|
348
|
+
if isinstance(params, dict):
|
|
349
|
+
# Dictionary params (e.g., for named placeholders)
|
|
350
|
+
for key, value in params.items():
|
|
351
|
+
expensive_attrs[f"{DB_QUERY_PARAMETER_TEMPLATE}.{key}"] = str(
|
|
352
|
+
value
|
|
353
|
+
)
|
|
354
|
+
elif isinstance(params, list | tuple):
|
|
355
|
+
# Sequential params (e.g., for %s or ? placeholders)
|
|
356
|
+
for i, value in enumerate(params):
|
|
357
|
+
expensive_attrs[f"{DB_QUERY_PARAMETER_TEMPLATE}.{i + 1}"] = str(
|
|
358
|
+
value
|
|
359
|
+
)
|
|
360
|
+
else:
|
|
361
|
+
# Single param (rare but possible)
|
|
362
|
+
expensive_attrs[f"{DB_QUERY_PARAMETER_TEMPLATE}.1"] = str(params)
|
|
363
|
+
|
|
364
|
+
span.set_attributes(expensive_attrs)
|
|
365
|
+
|
|
356
366
|
start = time.perf_counter()
|
|
357
367
|
try:
|
|
358
368
|
yield span
|
|
359
369
|
except Exception as exc:
|
|
360
370
|
# record_exception + set_status(ERROR) handled by
|
|
361
371
|
# start_as_current_span when the exception propagates out.
|
|
362
|
-
span.
|
|
372
|
+
if span.is_recording():
|
|
373
|
+
span.set_attribute(ERROR_TYPE, format_exception_type(exc))
|
|
363
374
|
raise
|
|
364
375
|
duration_s = time.perf_counter() - start
|
|
365
376
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
from plain.postgres.connection import DatabaseConnection
|
|
6
|
+
from plain.postgres.db import _db_conn
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@pytest.fixture
|
|
10
|
+
def _unblock_cursor() -> None:
|
|
11
|
+
"""Restore the real cursor method (blocked by the autouse _db_disabled fixture)."""
|
|
12
|
+
DatabaseConnection.cursor = getattr(DatabaseConnection, "_enabled_cursor")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@pytest.fixture
|
|
16
|
+
def _clean_connection():
|
|
17
|
+
"""Ensure the ContextVar starts empty and clean up any connection afterward."""
|
|
18
|
+
token = _db_conn.set(None)
|
|
19
|
+
yield
|
|
20
|
+
conn = _db_conn.get()
|
|
21
|
+
if conn is not None:
|
|
22
|
+
try:
|
|
23
|
+
conn.close()
|
|
24
|
+
except Exception:
|
|
25
|
+
pass
|
|
26
|
+
_db_conn.reset(token)
|
|
@@ -18,20 +18,6 @@ from plain.postgres.sources import runtime_pool_source
|
|
|
18
18
|
from plain.runtime import settings
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
@pytest.fixture
|
|
22
|
-
def _clean_connection():
|
|
23
|
-
"""Ensure the ContextVar starts empty and clean up any connection afterward."""
|
|
24
|
-
token = _db_conn.set(None)
|
|
25
|
-
yield
|
|
26
|
-
conn = _db_conn.get()
|
|
27
|
-
if conn is not None:
|
|
28
|
-
try:
|
|
29
|
-
conn.close()
|
|
30
|
-
except Exception:
|
|
31
|
-
pass
|
|
32
|
-
_db_conn.reset(token)
|
|
33
|
-
|
|
34
|
-
|
|
35
21
|
class TestPoolCheckoutReturn:
|
|
36
22
|
@pytest.mark.usefixtures("_unblock_cursor", "_clean_connection")
|
|
37
23
|
def test_checkout_and_return(self, setup_db):
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"""Tests for self-healing after a server-side connection close.
|
|
2
|
+
|
|
3
|
+
When Postgres closes a connection we're holding (restart, failover, idle
|
|
4
|
+
timeout), psycopg only notices on the next I/O — the operation fails and the
|
|
5
|
+
connection is marked closed. `ensure_connection()` must then discard the dead
|
|
6
|
+
connection and acquire a fresh one, instead of reusing the dead object on
|
|
7
|
+
every subsequent call.
|
|
8
|
+
|
|
9
|
+
The exception is inside an atomic block: swapping there would silently run
|
|
10
|
+
the rest of the block outside its transaction, so the dead connection stays
|
|
11
|
+
put and `Atomic.__exit__`'s error recovery drops it instead.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import psycopg
|
|
17
|
+
import pytest
|
|
18
|
+
|
|
19
|
+
from plain.postgres import transaction
|
|
20
|
+
from plain.postgres.db import get_connection
|
|
21
|
+
from plain.postgres.sources import runtime_pool_source
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _terminate_backend(pid: int) -> None:
|
|
25
|
+
"""Kill a backend from a separate pool connection."""
|
|
26
|
+
terminator = runtime_pool_source.acquire()
|
|
27
|
+
try:
|
|
28
|
+
with terminator.cursor() as cursor:
|
|
29
|
+
cursor.execute("SELECT pg_terminate_backend(%s)", (pid,))
|
|
30
|
+
finally:
|
|
31
|
+
runtime_pool_source.release(terminator)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _backend_pid(conn) -> int:
|
|
35
|
+
with conn.cursor() as cursor:
|
|
36
|
+
cursor.execute("SELECT pg_backend_pid()")
|
|
37
|
+
row = cursor.fetchone()
|
|
38
|
+
assert row is not None
|
|
39
|
+
return row[0]
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class TestDeadConnectionSelfHeal:
|
|
43
|
+
@pytest.mark.usefixtures("_unblock_cursor", "_clean_connection")
|
|
44
|
+
def test_closed_connection_replaced_on_next_use(self, setup_db):
|
|
45
|
+
"""A wrapper holding a closed psycopg connection acquires a fresh one."""
|
|
46
|
+
conn = get_connection()
|
|
47
|
+
with conn.cursor() as cursor:
|
|
48
|
+
cursor.execute("SELECT 1")
|
|
49
|
+
|
|
50
|
+
# Simulate the aftermath of a server-side close: the wrapper still
|
|
51
|
+
# holds a psycopg connection whose pgconn status is BAD.
|
|
52
|
+
assert conn.connection is not None
|
|
53
|
+
conn.connection.close()
|
|
54
|
+
assert conn.connection.closed
|
|
55
|
+
|
|
56
|
+
with conn.cursor() as cursor:
|
|
57
|
+
cursor.execute("SELECT 1")
|
|
58
|
+
assert cursor.fetchone() == (1,)
|
|
59
|
+
assert conn.connection is not None
|
|
60
|
+
assert not conn.connection.closed
|
|
61
|
+
|
|
62
|
+
@pytest.mark.usefixtures("_unblock_cursor", "_clean_connection")
|
|
63
|
+
def test_terminated_backend_errors_once_then_heals(self, setup_db):
|
|
64
|
+
"""A server-side kill fails the in-flight query, then self-heals."""
|
|
65
|
+
conn = get_connection()
|
|
66
|
+
pid = _backend_pid(conn)
|
|
67
|
+
|
|
68
|
+
_terminate_backend(pid)
|
|
69
|
+
|
|
70
|
+
# psycopg only detects the dead socket on I/O — the first use fails
|
|
71
|
+
# and marks the connection closed.
|
|
72
|
+
with pytest.raises(psycopg.OperationalError):
|
|
73
|
+
with conn.cursor() as cursor:
|
|
74
|
+
cursor.execute("SELECT 1")
|
|
75
|
+
assert conn.connection is not None
|
|
76
|
+
assert conn.connection.closed
|
|
77
|
+
|
|
78
|
+
# The next use discards the dead connection and acquires a fresh one.
|
|
79
|
+
with conn.cursor() as cursor:
|
|
80
|
+
cursor.execute("SELECT 1")
|
|
81
|
+
assert cursor.fetchone() == (1,)
|
|
82
|
+
assert _backend_pid(conn) != pid
|
|
83
|
+
|
|
84
|
+
@pytest.mark.usefixtures("_unblock_cursor", "_clean_connection")
|
|
85
|
+
def test_dead_connection_not_swapped_mid_atomic(self, setup_db):
|
|
86
|
+
"""Mid-atomic, the dead connection stays put — a silent swap would run
|
|
87
|
+
the rest of the block outside its transaction. Atomic.__exit__'s error
|
|
88
|
+
recovery drops it, and the next use heals."""
|
|
89
|
+
conn = get_connection()
|
|
90
|
+
|
|
91
|
+
def killed_mid_atomic() -> None:
|
|
92
|
+
with transaction.atomic():
|
|
93
|
+
pid = _backend_pid(conn)
|
|
94
|
+
_terminate_backend(pid)
|
|
95
|
+
with conn.cursor() as cursor:
|
|
96
|
+
cursor.execute("SELECT 1")
|
|
97
|
+
|
|
98
|
+
with pytest.raises(psycopg.OperationalError):
|
|
99
|
+
killed_mid_atomic()
|
|
100
|
+
|
|
101
|
+
# Atomic.__exit__ dropped the dead connection during rollback recovery.
|
|
102
|
+
assert conn.connection is None
|
|
103
|
+
|
|
104
|
+
with conn.cursor() as cursor:
|
|
105
|
+
cursor.execute("SELECT 1")
|
|
106
|
+
assert cursor.fetchone() == (1,)
|
|
107
|
+
|
|
108
|
+
@pytest.mark.usefixtures("_unblock_cursor", "_clean_connection")
|
|
109
|
+
def test_dead_connection_in_nested_atomic(self, setup_db):
|
|
110
|
+
"""Nested atomics: the inner savepoint rollback fails on the dead
|
|
111
|
+
connection and marks needs_rollback; the outer rollback then fails
|
|
112
|
+
too and drops the connection. The next use heals."""
|
|
113
|
+
conn = get_connection()
|
|
114
|
+
|
|
115
|
+
def killed_in_nested_atomic() -> None:
|
|
116
|
+
with transaction.atomic():
|
|
117
|
+
with transaction.atomic():
|
|
118
|
+
pid = _backend_pid(conn)
|
|
119
|
+
_terminate_backend(pid)
|
|
120
|
+
with conn.cursor() as cursor:
|
|
121
|
+
cursor.execute("SELECT 1")
|
|
122
|
+
|
|
123
|
+
with pytest.raises(psycopg.OperationalError):
|
|
124
|
+
killed_in_nested_atomic()
|
|
125
|
+
|
|
126
|
+
# The outer Atomic.__exit__ dropped the dead connection.
|
|
127
|
+
assert conn.connection is None
|
|
128
|
+
|
|
129
|
+
with conn.cursor() as cursor:
|
|
130
|
+
cursor.execute("SELECT 1")
|
|
131
|
+
assert cursor.fetchone() == (1,)
|
|
@@ -15,8 +15,10 @@ from opentelemetry.sdk.metrics.export import InMemoryMetricReader
|
|
|
15
15
|
from opentelemetry.sdk.trace.export.in_memory_span_exporter import (
|
|
16
16
|
InMemorySpanExporter,
|
|
17
17
|
)
|
|
18
|
+
from opentelemetry.trace import NoOpTracer
|
|
18
19
|
from psycopg_pool import PoolTimeout
|
|
19
20
|
|
|
21
|
+
from plain.postgres import otel as postgres_otel
|
|
20
22
|
from plain.postgres.db import get_connection
|
|
21
23
|
from plain.postgres.otel import register_pool_observables
|
|
22
24
|
from plain.postgres.sources import runtime_pool_source
|
|
@@ -60,6 +62,33 @@ class TestQuerySpanAttributes:
|
|
|
60
62
|
assert "server.port" in attrs
|
|
61
63
|
assert attrs["server.port"] == attrs.get("network.peer.port")
|
|
62
64
|
|
|
65
|
+
def test_not_recording_skips_stack_walk(
|
|
66
|
+
self, monkeypatch: pytest.MonkeyPatch
|
|
67
|
+
) -> None:
|
|
68
|
+
# Cheap attributes still build unconditionally (attribute-aware
|
|
69
|
+
# samplers see them at span creation), but the per-query stack walk
|
|
70
|
+
# must only happen when the span actually records.
|
|
71
|
+
stack_walks: list[int] = []
|
|
72
|
+
|
|
73
|
+
def counting_code_attributes() -> dict[str, Any]:
|
|
74
|
+
stack_walks.append(1)
|
|
75
|
+
return {}
|
|
76
|
+
|
|
77
|
+
monkeypatch.setattr(
|
|
78
|
+
postgres_otel, "_get_code_attributes", counting_code_attributes
|
|
79
|
+
)
|
|
80
|
+
monkeypatch.setattr(postgres_otel, "tracer", NoOpTracer())
|
|
81
|
+
|
|
82
|
+
class StubDb:
|
|
83
|
+
settings_dict: dict[str, Any] = {}
|
|
84
|
+
|
|
85
|
+
with postgres_otel.db_span(StubDb(), "SELECT 1") as span: # ty: ignore[invalid-argument-type]
|
|
86
|
+
pass
|
|
87
|
+
|
|
88
|
+
assert span is not None
|
|
89
|
+
assert not span.is_recording()
|
|
90
|
+
assert not stack_walks
|
|
91
|
+
|
|
63
92
|
|
|
64
93
|
class TestReturnedRowsMetric:
|
|
65
94
|
@pytest.mark.usefixtures("db")
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import pytest
|
|
4
|
-
|
|
5
|
-
from plain.postgres.connection import DatabaseConnection
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
@pytest.fixture
|
|
9
|
-
def _unblock_cursor() -> None:
|
|
10
|
-
"""Restore the real cursor method (blocked by the autouse _db_disabled fixture)."""
|
|
11
|
-
DatabaseConnection.cursor = getattr(DatabaseConnection, "_enabled_cursor")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/fields/related_descriptors.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/fields/reverse_descriptors.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/introspection/health/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/introspection/health/context.py
RENAMED
|
File without changes
|
{plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/introspection/health/helpers.py
RENAMED
|
File without changes
|
{plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/introspection/health/ownership.py
RENAMED
|
File without changes
|
{plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/introspection/health/runner.py
RENAMED
|
File without changes
|
{plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/introspection/health/types.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/migrations/operations/__init__.py
RENAMED
|
File without changes
|
{plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/migrations/operations/base.py
RENAMED
|
File without changes
|
{plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/migrations/operations/fields.py
RENAMED
|
File without changes
|
{plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/migrations/operations/models.py
RENAMED
|
File without changes
|
{plain_postgres-0.108.0 → plain_postgres-0.108.1}/plain/postgres/migrations/operations/special.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|