Skip to content

Fix migration 0156 CheckViolation by normalizing invalid base_path values - #8068

Open
dkliban wants to merge 6 commits into
pulp:mainfrom
dkliban:PULP-2345/fix-migration-0156
Open

Fix migration 0156 CheckViolation by normalizing invalid base_path values#8068
dkliban wants to merge 6 commits into
pulp:mainfrom
dkliban:PULP-2345/fix-migration-0156

Conversation

@dkliban

@dkliban dkliban commented Sep 5, 2026

Copy link
Copy Markdown
Member

Summary

Migration core.0156_alter_contentartifact_relative_path_and_more fails with a CheckViolation when any existing core_distribution.base_path value does not satisfy the relative_path domain check constraint introduced in migration 0155.

Reproduces as reported in #8067: after a failed upgrade to 3.117.0 (deadlock during migration), the retry with 3.117.1 fails with:

psycopg.errors.CheckViolation: value for domain relative_path violates check constraint "relative_path_check"

Root cause: AlterField in migration 0156 changes core_distribution.base_path from text to the relative_path domain. PostgreSQL validates all existing rows against the domain's check constraint during this operation. Any path value containing whitespace, ?, #, double-slashes, leading/trailing slashes, or dot/dotdot components violates the constraint and causes the migration to abort.

Fix: Add a RunPython step before the AlterField operation that:

  • Finds all rows whose base_path violates the constraint (using the same regex as the domain)
  • Automatically normalizes fixable paths (strips whitespace, query strings, leading/trailing slashes, collapses double-slashes, removes dot/dotdot components)
  • Raises a descriptive RuntimeError listing any paths that cannot be automatically fixed, so administrators can correct them before retrying

Tests: Unit tests for _normalize_path (parametrized, no DB required) and for fix_base_path_violations (mock-based, tests the normalize, skip-clean, and unfixable-path code paths).

Closes #8067

Test plan

  • pytest pulpcore/tests/unit/models/test_0156_migration.py passes
  • Migration 0156 applies cleanly on a database with no invalid base_path values
  • Migration 0156 applies cleanly on a database with fixable invalid base_path values (trailing slash, whitespace, query string)
  • Migration 0156 raises a descriptive error for unfixable base_path values (e.g. bare .)

🤖 Generated with Claude Code

dkliban and others added 6 commits September 4, 2026 21:21
…e cast (issue pulp#8067)

Migration 0156 fails with a CheckViolation when any existing row in
core_distribution has a base_path value that doesn't satisfy the
relative_path domain constraint introduced in 0155.

Add a RunPython step before the AlterField operation that:
- Finds all rows whose base_path values would fail the constraint
- Normalizes them (strips whitespace, leading/trailing slashes, double
  slashes, and bare dot/dotdot components)
- Raises a RuntimeError with the offending rows listed if any path
  cannot be automatically fixed, allowing administrators to correct
  the data manually before retrying the migration

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…6 fix

- Remove unused 'import django.db.models.expressions' (ruff I001)
- Add unit tests for _normalize_path and fix_base_path_violations:
  * Parametrized tests covering trailing/leading slashes, whitespace,
    query strings, fragments, dot/dotdot components, and clean paths
  * Mock-based tests for the database update path and unfixable path
    error handling

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…isort config

ruff isort treats pulpcore as 'second-party' with its own import group after
third-party packages (django.*). Separate it from the Django imports with a
blank line to satisfy the I001 rule.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- Remove unused 'call' import (ruff F401)
- Remove unused 'pk'/'clean_path' variables from skips-clean-rows test (ruff F841)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- Join SQL string onto single line (ruff format prefers no implicit concatenation)
- Remove blank line after class declaration (ruff format)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
ruff format wraps lines >88 chars; the patch() calls in tests had
very long module paths that needed to be reformatted.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

upgrading to 3.117.1 from failed upgrade to 3.117.0 also fails

1 participant