Skip to main content

Running the Migration

Configuration

Create or update apps/migration/.env with:

VariableDescription
DATABASE_URLPostgreSQL connection URL (same as API)
SNIPEIT_BASE_URLInternal or public Snipe-IT URL
SNIPEIT_API_TOKENSnipe-IT personal access token

CLI reference

python apps/migration/makerlab_migrate/cli.py [OPTIONS]
OptionDefaultDescription
--dump-path PATH(required)Path to the legacy wiki PostgreSQL dump directory
--dry-runfalsePreview all operations without writing
--entityallWhich entities to migrate: users, projects, equipment, or all
--limit N(none)Limit the number of records per entity (useful for testing)
--since-legacy-id X(none)Start from a specific legacy ID (manual incremental)
--incrementalfalseUse checkpoint tracking for automatic incremental runs
--batch-size N100Records per batch (for Snipe-IT rate limiting)
--skip-snipeitfalseMigrate to PostgreSQL only, skip Snipe-IT
--validate-onlyfalseParse and validate the dump without any DB operations

Exit codes

CodeMeaning
0Success
1Configuration error (missing env vars or invalid paths)
2Database connection error
3Snipe-IT API error
4Dump parsing error
5Validation error (schema constraints would be violated)

Step 1: Validate the dump

python apps/migration/makerlab_migrate/cli.py \
--dump-path /path/to/dump-1776931288 \
--validate-only

Parses the dump and reports any issues (missing fields, invalid values) without writing anything.

Step 2: Test with a small batch (PostgreSQL only)

python apps/migration/makerlab_migrate/cli.py \
--dump-path /path/to/dump-1776931288 \
--skip-snipeit \
--limit 10

Tests the user and project migration with 10 records, skipping Snipe-IT.

Step 3: Full dry-run

python apps/migration/makerlab_migrate/cli.py \
--dump-path /path/to/dump-1776931288 \
--dry-run

Simulates the complete migration (including Snipe-IT calls) without writing any data.

Step 4: Migrate users only

python apps/migration/makerlab_migrate/cli.py \
--dump-path /path/to/dump-1776931288 \
--entity users

Step 5: Migrate projects

python apps/migration/makerlab_migrate/cli.py \
--dump-path /path/to/dump-1776931288 \
--entity projects

Projects require users to exist first (FK dependency).

Step 6: Migrate equipment

python apps/migration/makerlab_migrate/cli.py \
--dump-path /path/to/dump-1776931288 \
--entity equipment

Equipment migration is self-contained.

Step 7: Full migration (all entities)

python apps/migration/makerlab_migrate/cli.py \
--dump-path /path/to/dump-1776931288

Runs all phases in order: users → projects → equipment.


Expected output

The migration tool logs structured JSON-like output to stdout:

{"entity": "user", "legacy_id": 42, "action": "INSERT", ...}
{"entity": "project", "legacy_id": 7, "action": "UPDATE", ...}
...
Phase 1 (Users) complete: 150 users
Phase 2 (Projects) complete: 48 projects, 92 members
Phase 3 (Equipment) complete: 35 models, 120 assets

At the end, summary counts are printed for inserted, updated, and skipped records.


Rollback

The migration is idempotent — re-running after a failure is safe. Records are upserted, not duplicated.

If data corruption is suspected:

  • Restore PostgreSQL from a pre-migration backup.
  • Wipe and re-initialize Snipe-IT assets by resetting the snipeit_db_data volume.
  • Re-run the migration.

The legacy_id columns in PostgreSQL allow selective deletion of migrated records if needed.