Skip to content

Fix SQLite migration compatibility and idempotency issues - #1006

Open
Bornunique911 wants to merge 20 commits into
OWASP:mainfrom
Bornunique911:fix/sqlite-migration-idempotency
Open

Fix SQLite migration compatibility and idempotency issues#1006
Bornunique911 wants to merge 20 commits into
OWASP:mainfrom
Bornunique911:fix/sqlite-migration-idempotency

Conversation

@Bornunique911

@Bornunique911 Bornunique911 commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Problem

Several recent migrations were not fully compatible with SQLite, causing errors when developers run
make migrate-upgrade or ./scripts/update-cwe.sh:

  • op.create_unique_constraint() after CREATE TABLE fails with No support for ALTER of constraints in SQLite dialect.

  • Missing document_metadata column in cre and node tables causes no such column errors.

  • Missing embedding_vec column in embeddings table causes no such column: embeddings.embedding_vec.

  • Some migrations are not idempotent, causing table already exists errors on re-runs.

Solution

  • 9f1a2b3c4d5e – Define UniqueConstraint inside CREATE TABLE; add table_exists guards.

  • 055dbd9f8bfe – Add document_metadata with column existence checks (new migration).

  • 967016ee10fa – Add embedding_vec as TEXT for SQLite with existence check (new migration).

Testing

  • ✅ Fresh SQLite database:

make migrate-upgrademake upstream-sync./scripts/update-cwe.sh all succeed.

  • ✅ Existing database: re-runs are idempotent, skip already-created objects.

  • ✅ No regressions for PostgreSQL.

Impact

  • Developers using SQLite can now run migrations and import data without manual workarounds.

  • Makes the project more contributor‑friendly for SQLite users.

Ready for review. Let me know if any adjustments are needed.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Summary by CodeRabbit

  • New Features

    • Added support for storing embedding vector data.
    • Added persistent storage for artifact ingestion records.
    • Added document metadata fields for CRE and node records.
  • Bug Fixes

    • Database upgrades now safely handle existing or partially applied schemas.
    • Missing tables, columns, and uniqueness rules are restored without disrupting existing data.
    • Database downgrades now cleanly remove added schema elements.

Walkthrough

The migrations conditionally add and remove nullable metadata and embedding columns. They also conditionally create artifact ingestion tables, repair unique constraints, and drop tables in dependency order.

Changes

Migration persistence changes

Layer / File(s) Summary
Document and embedding columns
migrations/versions/967016ee10fa_add_embedding_vec_to_embeddings_for_.py, migrations/versions/b5ac48010165_add_missing_document_metadata_column_to_.py
The migrations inspect existing columns before adding nullable Text columns. Downgrades remove each column only when it exists.
Artifact ingestion tables
migrations/versions/9f1a2b3c4d5e_add_artifact_ingest_persistence.py
The migration conditionally creates artifact_ingest_event and ingest_chunk, repairs expected unique constraints on existing tables, and drops tables in reverse dependency order.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Possibly related PRs

Suggested reviewers: pa04rth, paoga87, robvanderveer

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the primary SQLite compatibility and migration idempotency fixes.
Description check ✅ Passed The description directly explains the SQLite migration problems, implemented fixes, testing, and expected impact.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
migrations/versions/055dbd9f8bfe_add_document_metadata_to_cre_and_node.py (1)

11-21: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use sa.inspect(conn) instead of Inspector.from_engine(conn).

The unpinned runtime SQLAlchemy dependency can resolve to SQLAlchemy 2.x, where Inspector.from_engine() is deprecated. Replace the duplicated calls in the referenced migrations with the supported inspection entry point.

Proposed change
-from sqlalchemy.engine.reflection import Inspector
...
-    inspector = Inspector.from_engine(conn)
+    inspector = sa.inspect(conn)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@migrations/versions/055dbd9f8bfe_add_document_metadata_to_cre_and_node.py`
around lines 11 - 21, Replace the deprecated Inspector.from_engine(conn) usage
with sa.inspect(conn) in the column_exists helper in
migrations/versions/055dbd9f8bfe_add_document_metadata_to_cre_and_node.py (lines
11-21), migrations/versions/967016ee10fa_add_embedding_vec_to_embeddings_for_.py
(lines 11-21), and
migrations/versions/9f1a2b3c4d5e_add_artifact_ingest_persistence.py (lines
11-21). Preserve the existing column inspection behavior and remove any
now-unused Inspector imports.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@migrations/versions/055dbd9f8bfe_add_document_metadata_to_cre_and_node.py`:
- Around line 39-43: The downgrade in
migrations/versions/055dbd9f8bfe_add_document_metadata_to_cre_and_node.py at
lines 39-43 must remove document_metadata from both cre and node using the
existing SQLite batch-table migration pattern, replacing the no-op downgrade.
Apply the same reversible downgrade change in
migrations/versions/967016ee10fa_add_embedding_vec_to_embeddings_for_.py at
lines 31-33 to remove embedding_vec from embeddings, and add downgrade coverage
for both revisions.

In `@migrations/versions/9f1a2b3c4d5e_add_artifact_ingest_persistence.py`:
- Around line 24-71: Update the migration logic around artifact_ingest_event and
ingest_chunk so existing tables are inspected for
uq_artifact_ingest_event_run_artifact and uq_ingest_chunk_artifact_chunk. When
either constraint is missing, rebuild or otherwise alter the table to add it
before the migration completes; do not silently skip DDL, and fail the migration
if the constraint cannot be repaired.

---

Nitpick comments:
In `@migrations/versions/055dbd9f8bfe_add_document_metadata_to_cre_and_node.py`:
- Around line 11-21: Replace the deprecated Inspector.from_engine(conn) usage
with sa.inspect(conn) in the column_exists helper in
migrations/versions/055dbd9f8bfe_add_document_metadata_to_cre_and_node.py (lines
11-21), migrations/versions/967016ee10fa_add_embedding_vec_to_embeddings_for_.py
(lines 11-21), and
migrations/versions/9f1a2b3c4d5e_add_artifact_ingest_persistence.py (lines
11-21). Preserve the existing column inspection behavior and remove any
now-unused Inspector imports.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: 0b0c9beb-ffbf-47a6-a28f-116a34aae300

📥 Commits

Reviewing files that changed from the base of the PR and between 3ac3d64 and 0580f51.

📒 Files selected for processing (3)
  • migrations/versions/055dbd9f8bfe_add_document_metadata_to_cre_and_node.py
  • migrations/versions/967016ee10fa_add_embedding_vec_to_embeddings_for_.py
  • migrations/versions/9f1a2b3c4d5e_add_artifact_ingest_persistence.py

Comment thread migrations/versions/055dbd9f8bfe_add_document_metadata_to_cre_and_node.py Outdated
Comment thread migrations/versions/9f1a2b3c4d5e_add_artifact_ingest_persistence.py Outdated
Bornunique911 added a commit to Bornunique911/OpenCRE that referenced this pull request Aug 5, 2026
…ints

- Add downgrades to 055dbd9f8bfe and 967016ee10fa to drop added columns
- Replace deprecated Inspector.from_engine(conn) with sa.inspect(conn)
- In 9f1a2b3c4d5e, verify that existing tables have the required unique
  constraints; add them via batch_alter_table if missing
- Ensure migration fails if constraints cannot be added

Addresses PR review comments OWASP#1006
@Bornunique911

Copy link
Copy Markdown
Contributor Author

Before change on the main website opencre.org/node/standard/CWE :

image

After change locally on 127.0.0.1:5000/node/standard/CWE :

image

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
migrations/versions/9f1a2b3c4d5e_add_artifact_ingest_persistence.py (1)

94-97: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Track table ownership before dropping in downgrade().

upgrade() may only add the missing unique constraints to existing artifact_ingest_event or ingest_chunk tables, while downgrade() always runs op.drop_table() for both. If a pre-existing table was adopted instead of created here, downgrade destroys its rows and schema. Track ownership or downgrade only constraint-alterations made by this revision.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@migrations/versions/9f1a2b3c4d5e_add_artifact_ingest_persistence.py` around
lines 94 - 97, Update the migration’s upgrade/downgrade flow to track whether
artifact_ingest_event and ingest_chunk were created by this revision versus
merely adopted with added constraints. In downgrade(), drop only tables owned
and created by this revision; for pre-existing tables, revert only the unique
constraints added by this migration and preserve their rows and schema.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@migrations/versions/055dbd9f8bfe_add_document_metadata_to_cre_and_node.py`:
- Around line 38-43: Align downgrade ownership checks with the conditional
upgrades: in
migrations/versions/055dbd9f8bfe_add_document_metadata_to_cre_and_node.py lines
38-43, update downgrade() to drop document_metadata from cre and node only when
each column exists, preserving pre-existing columns; in
migrations/versions/967016ee10fa_add_embedding_vec_to_embeddings_for_.py lines
30-33, apply the same existence check before dropping embedding_vec from
embeddings. Add downgrade coverage for absent columns and populated pre-existing
columns at both sites.

In `@migrations/versions/9f1a2b3c4d5e_add_artifact_ingest_persistence.py`:
- Around line 57-61: Before the artifact_ingest_event batch rewrite and
create_unique_constraint operation, handle the ingest_chunk foreign key
explicitly: temporarily enable foreign-key enforcement, drop the child
constraint, and recreate it with its existing cascade behavior after the
rewrite. Add a regression test covering pre-existing artifact_ingest_event rows
and verifying the ingest_chunk relationship remains valid.
- Around line 57-61: Update the existing-table migration paths using
op.batch_alter_table for artifact_ingest_event and ingest_chunk so unnamed
UNIQUE constraints are preserved during SQLite table recreation. Copy or replace
each supported unnamed uniqueness rule before adding the named constraint,
reject unsupported legacy schemas, or use recreate="always" with explicit
table_args; ensure no existing uniqueness rule is silently dropped.
- Around line 22-26: Update constraint_exists to validate both the constraint
name and its column_names against the migration’s expected target columns,
returning true only for an exact definition match; if the name exists with
different columns, do not treat it as present so the migration can correct it.
Apply the same validation at the checks around the constraints named
uq_artifact_ingest_event_run_artifact and uq_ingest_chunk_artifact_chunk.

---

Outside diff comments:
In `@migrations/versions/9f1a2b3c4d5e_add_artifact_ingest_persistence.py`:
- Around line 94-97: Update the migration’s upgrade/downgrade flow to track
whether artifact_ingest_event and ingest_chunk were created by this revision
versus merely adopted with added constraints. In downgrade(), drop only tables
owned and created by this revision; for pre-existing tables, revert only the
unique constraints added by this migration and preserve their rows and schema.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: 7d32bd9f-c55b-4fa9-8cb2-af49b08dfa50

📥 Commits

Reviewing files that changed from the base of the PR and between 0580f51 and f4649ad.

📒 Files selected for processing (3)
  • migrations/versions/055dbd9f8bfe_add_document_metadata_to_cre_and_node.py
  • migrations/versions/967016ee10fa_add_embedding_vec_to_embeddings_for_.py
  • migrations/versions/9f1a2b3c4d5e_add_artifact_ingest_persistence.py

Comment thread migrations/versions/055dbd9f8bfe_add_document_metadata_to_cre_and_node.py Outdated
Comment thread migrations/versions/9f1a2b3c4d5e_add_artifact_ingest_persistence.py Outdated
Comment thread migrations/versions/9f1a2b3c4d5e_add_artifact_ingest_persistence.py Outdated
@Bornunique911

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@northdpole

Copy link
Copy Markdown
Collaborator

Thanks for the SQLite migration work. Please wait for #995 to land first, then rebase this PR onto main (with #995 merged) so we don’t ship two competing document_metadata migrations.

Why #995 first

Both PRs add document_metadata on cre/node, but with different revision IDs / parents / column types (JSON vs Text). Merging both as-is would fork Alembic lineage. #995 is the Postgres bootstrap fix for #994; this PR should build on that head.

Fixes after rebase

  1. Rebase onto post-Fix migration bootstrap failures on fresh Postgres #995 main — drop / fold any duplicate document_metadata migration; keep the SQLite-specific pieces (9f1a2b3c4d5e unique-constraint fix, embedding_vec for SQLite).
  2. Real down_revisions — current placeholders (# or whatever the current head is, similar comments) need to point at the actual head after Fix migration bootstrap failures on fresh Postgres #995.
  3. Drop print() in migrations — use logging or silent existence checks only.
  4. Align column type with whatever Fix migration bootstrap failures on fresh Postgres #995 shipped for document_metadata (don’t diverge JSON vs Text across dialects unless intentional and documented).

Happy to re-review once rebased on #995.

@Bornunique911

Copy link
Copy Markdown
Contributor Author

Thanks for the SQLite migration work. Please wait for #995 to land first, then rebase this PR onto main (with #995 merged) so we don’t ship two competing document_metadata migrations.

Why #995 first

Both PRs add document_metadata on cre/node, but with different revision IDs / parents / column types (JSON vs Text). Merging both as-is would fork Alembic lineage. #995 is the Postgres bootstrap fix for #994; this PR should build on that head.

Fixes after rebase

  1. Rebase onto post-Fix migration bootstrap failures on fresh Postgress #995 main — drop / fold any duplicate document_metadata migration; keep the SQLite-specific pieces (9f1a2b3c4d5e unique-constraint fix, embedding_vec for SQLite).
  2. Real down_revisions — current placeholders (# or whatever the current head is, similar comments) need to point at the actual head after Fix migration bootstrap failures on fresh Postgress #995.
  3. Drop print() in migrations — use logging or silent existence checks only.
  4. Align column type with whatever Fix migration bootstrap failures on fresh Postgress #995 shipped for document_metadata (don’t diverge JSON vs Text across dialects unless intentional and documented).

Happy to re-review once rebased on #995.

Thanks for the review – that makes sense. I'll wait for #995 to merge, then rebase this PR onto main.

After rebasing, I'll:

  • Drop/remove 055dbd9f8bfe_add_document_metadata_to_cre_and_node.py – since Fix migration bootstrap failures on fresh Postgres #995 already adds the document_metadata columns, we'll use that migration and keep only our SQLite‑specific adjustments.

  • Keep the following SQLite fixes:

    9f1a2b3c4d5e – unique constraint fix for artifact_ingest_event and ingest_chunk.

    967016ee10fa – add embedding_vec to embeddings for SQLite (if not already present).

  • Update down_revision in 967016ee10fa to point to the actual head revision from Fix migration bootstrap failures on fresh Postgres #995 (no placeholders).

  • Replace print() statements with silent existence checks or use Alembic's logging (op.logger.info()) if needed.

  • Align document_metadata column type with what Fix migration bootstrap failures on fresh Postgres #995 shipped (JSON or Text) – I'll check the model and adjust accordingly so we don't diverge across dialects unintentionally.

Once I've rebased and cleaned up, I'll re‑request your review. Thanks for the guidance!

@northdpole

Copy link
Copy Markdown
Collaborator

Waiting on #995, then please rebase onto main (currently ~8 commits behind; will be more after #995).

After rebase: drop/fold duplicate document_metadata migration, fix real down_revisions (no placeholder comments), remove print() from migrations. Ping when green.

@DevPatils

Copy link
Copy Markdown
Contributor

Waiting on #995, then please rebase onto main (currently ~8 commits behind; will be more after #995).

After rebase: drop/fold duplicate document_metadata migration, fix real down_revisions (no placeholder comments), remove print() from migrations. Ping when green.

#995 is rebased please check @northdpole !

@northdpole

Copy link
Copy Markdown
Collaborator

#995 has merged. Please rebase this PR onto latest main, fold/drop any duplicate document_metadata migration, and ping for re-review.

…ints

- Add downgrades to 055dbd9f8bfe and 967016ee10fa to drop added columns
- Replace deprecated Inspector.from_engine(conn) with sa.inspect(conn)
- In 9f1a2b3c4d5e, verify that existing tables have the required unique
  constraints; add them via batch_alter_table if missing
- Ensure migration fails if constraints cannot be added

Addresses PR review comments OWASP#1006
@Bornunique911
Bornunique911 force-pushed the fix/sqlite-migration-idempotency branch from c79da22 to d4bea6f Compare August 7, 2026 09:26

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
migrations/versions/b5ac48010165_add_missing_document_metadata_column_to_.py (1)

32-41: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Remove the print() calls from the migration.

The PR objectives explicitly require migrations without print() statements. Remove the four unconditional stdout writes. Keep migration diagnostics in the project’s standard logging path if diagnostics are required.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@migrations/versions/b5ac48010165_add_missing_document_metadata_column_to_.py`
around lines 32 - 41, Remove all four print() calls from the migration’s
column-existence branches, including the messages for the cre and node tables.
Preserve the existing column checks and op.add_column operations; use the
project’s standard logging path only if migration diagnostics are required.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@migrations/versions/b5ac48010165_add_missing_document_metadata_column_to_.py`:
- Around line 44-58: The downgrade function must not drop pre-existing
document_metadata columns, since column_exists only confirms presence, not
ownership. Make the migration ownership-aware by folding this revision into the
original `#995` migration or recording which columns upgrade() actually added,
then have downgrade() drop only those columns; add regression coverage for both
cre and node.
- Around line 31-38: Update the migration’s document_metadata column definitions
for both cre and node to use sa.JSON() instead of sa.Text(), matching the JSON
handling in the application. Remove the related migration print() calls while
preserving the existing column-existence checks and conditional additions.

---

Nitpick comments:
In
`@migrations/versions/b5ac48010165_add_missing_document_metadata_column_to_.py`:
- Around line 32-41: Remove all four print() calls from the migration’s
column-existence branches, including the messages for the cre and node tables.
Preserve the existing column checks and op.add_column operations; use the
project’s standard logging path only if migration diagnostics are required.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: e67e0d87-a4a7-4297-8073-46ddaafd26af

📥 Commits

Reviewing files that changed from the base of the PR and between c79da22 and 50e69a7.

📒 Files selected for processing (1)
  • migrations/versions/b5ac48010165_add_missing_document_metadata_column_to_.py

Comment thread migrations/versions/b5ac48010165_add_missing_document_metadata_column_to_.py Outdated
Comment thread migrations/versions/b5ac48010165_add_missing_document_metadata_column_to_.py Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants