{"id":47592851,"url":"https://github.com/bluedenim/vmigration-helper","last_synced_at":"2026-04-01T17:42:18.634Z","repository":{"id":45312870,"uuid":"376691529","full_name":"bluedenim/vmigration-helper","owner":"bluedenim","description":"Helpers for working with Django migrations","archived":false,"fork":false,"pushed_at":"2026-03-18T19:54:28.000Z","size":83,"stargazers_count":1,"open_issues_count":0,"forks_count":4,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-03-23T00:51:53.336Z","etag":null,"topics":["django","migration","rollback"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bluedenim.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-06-14T03:21:16.000Z","updated_at":"2026-03-18T19:54:33.000Z","dependencies_parsed_at":"2024-11-15T21:51:28.110Z","dependency_job_id":null,"html_url":"https://github.com/bluedenim/vmigration-helper","commit_stats":{"total_commits":17,"total_committers":2,"mean_commits":8.5,"dds":"0.11764705882352944","last_synced_commit":"cd64a34d3f343616aefe97dd783faa20be0f05d2"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/bluedenim/vmigration-helper","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluedenim%2Fvmigration-helper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluedenim%2Fvmigration-helper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluedenim%2Fvmigration-helper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluedenim%2Fvmigration-helper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bluedenim","download_url":"https://codeload.github.com/bluedenim/vmigration-helper/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluedenim%2Fvmigration-helper/sbom","scorecard":{"id":244477,"data":{"date":"2025-08-11","repo":{"name":"github.com/bluedenim/vmigration-helper","commit":"ef9d5ffde910cdcca66a39313dbed719d8cfd11b"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.5,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":0,"reason":"Found 1/22 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/main.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:10: update your workflow using https://app.stepsecurity.io/secureworkflow/bluedenim/vmigration-helper/main.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/bluedenim/vmigration-helper/main.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/bluedenim/vmigration-helper/main.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:40: update your workflow using https://app.stepsecurity.io/secureworkflow/bluedenim/vmigration-helper/main.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/main.yml:45: update your workflow using https://app.stepsecurity.io/secureworkflow/bluedenim/vmigration-helper/main.yml/master?enable=pin","Warn: containerImage not pinned by hash: Dockerfile:1: pin your Docker image by updating python:3.9 to python:3.9@sha256:9edfcfbe4d1bc6aabe0dd49a0e9cf625d83524edf574bc8cca7b1214bd9d170e","Warn: pipCommand not pinned by hash: Dockerfile:5","Warn: downloadThenRun not pinned by hash: Dockerfile:8","Warn: pipCommand not pinned by hash: .github/workflows/main.yml:16","Warn: downloadThenRun not pinned by hash: .github/workflows/main.yml:18","Info:   0 out of   4 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned","Info:   0 out of   1 containerImage dependencies pinned","Info:   0 out of   2 pipCommand dependencies pinned","Info:   0 out of   2 downloadThenRun dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/main.yml:29"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Vulnerabilities","score":6,"reason":"4 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: PYSEC-2025-47 / GHSA-7xr5-9hcq-chf9","Warn: Project is vulnerable to: PYSEC-2025-37 / GHSA-8j24-cjrq-gr2m","Warn: Project is vulnerable to: PYSEC-2025-13 / GHSA-p3fp-8748-vqfq","Warn: Project is vulnerable to: PYSEC-2025-1 / GHSA-qcgg-j2x8-h9g8"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 23 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-17T07:18:31.840Z","repository_id":45312870,"created_at":"2025-08-17T07:18:31.841Z","updated_at":"2025-08-17T07:18:31.841Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31290547,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["django","migration","rollback"],"created_at":"2026-04-01T17:42:17.829Z","updated_at":"2026-04-01T17:42:18.629Z","avatar_url":"https://github.com/bluedenim.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Van's Migration Helper\n\nDjango commands to help with running Django migrations.\n\n## Installation\n\n* Add the dependency to your environment:\n\n  ```\n  pip install vmigration-helper\n  ```\n\n* Add the app `vmgration_helper.apps.VMigrationHelperConfig` to your list of installed apps in your settings:\n\n  ```\n  INSTALLED_APPS = [\n    ...\n    'vmigration_helper.apps.VMigrationHelperConfig',\n    ...\n  ]\n  ```\n\n\n## Commands\n\n### migration_records\n\nShows existing migration records in your `django_migration` table.\n\n```\n\u003e python manage.py migration_records\n    ID Applied                           App Name\n     1 2024-12-06T18:15:03+0000 contenttypes 0001_initial\n     2 2024-12-06T18:15:03+0000         auth 0001_initial\n     3 2024-12-06T18:15:03+0000        admin 0001_initial\n     4 2024-12-06T18:15:03+0000        admin 0002_logentry_remove_auto_add\n     5 2024-12-06T18:15:03+0000        admin 0003_logentry_add_action_flag_choices\n     6 2024-12-06T18:15:03+0000 contenttypes 0002_remove_content_type_name\n     7 2024-12-06T18:15:03+0000         auth 0002_alter_permission_name_max_length\n     8 2024-12-06T18:15:03+0000         auth 0003_alter_user_email_max_length\n     9 2024-12-06T18:15:03+0000         auth 0004_alter_user_username_opts\n    10 2024-12-06T18:15:03+0000         auth 0005_alter_user_last_login_null\n    11 2024-12-06T18:15:03+0000         auth 0006_require_contenttypes_0002\n    12 2024-12-06T18:15:03+0000         auth 0007_alter_validators_add_error_messages\n    13 2024-12-06T18:15:03+0000         auth 0008_alter_user_username_max_length\n    14 2024-12-06T18:15:03+0000         auth 0009_alter_user_last_name_max_length\n    15 2024-12-06T18:15:03+0000         auth 0010_alter_group_name_max_length\n    16 2024-12-06T18:15:03+0000         auth 0011_update_proxy_permissions\n    17 2024-12-06T18:15:03+0000         auth 0012_alter_user_first_name_max_length\n    18 2024-12-06T18:15:03+0000     sessions 0001_initial\n\n\u003e python manage.py migration_records --format csv\nID,Applied,App,Name\n1,2024-12-06T18:15:03+0000,contenttypes,0001_initial\n2,2024-12-06T18:15:03+0000,auth,0001_initial\n3,2024-12-06T18:15:03+0000,admin,0001_initial\n4,2024-12-06T18:15:03+0000,admin,0002_logentry_remove_auto_add\n5,2024-12-06T18:15:03+0000,admin,0003_logentry_add_action_flag_choices\n6,2024-12-06T18:15:03+0000,contenttypes,0002_remove_content_type_name\n7,2024-12-06T18:15:03+0000,auth,0002_alter_permission_name_max_length\n8,2024-12-06T18:15:03+0000,auth,0003_alter_user_email_max_length\n9,2024-12-06T18:15:03+0000,auth,0004_alter_user_username_opts\n10,2024-12-06T18:15:03+0000,auth,0005_alter_user_last_login_null\n11,2024-12-06T18:15:03+0000,auth,0006_require_contenttypes_0002\n12,2024-12-06T18:15:03+0000,auth,0007_alter_validators_add_error_messages\n13,2024-12-06T18:15:03+0000,auth,0008_alter_user_username_max_length\n14,2024-12-06T18:15:03+0000,auth,0009_alter_user_last_name_max_length\n15,2024-12-06T18:15:03+0000,auth,0010_alter_group_name_max_length\n16,2024-12-06T18:15:03+0000,auth,0011_update_proxy_permissions\n17,2024-12-06T18:15:03+0000,auth,0012_alter_user_first_name_max_length\n18,2024-12-06T18:15:03+0000,sessions,0001_initial\n```\n\n\nThese are the records of migrations applied. The fields indicate:\n  * ID - the ID of the migration record\n  * Applied - when the migration was applied \n  * App - name of the Django app\n  * Name - name of the migration \n\n#### Optional parameters:\n\n  * `--format (console | csv)` print the info in CSV or friendlier console format (default)\n  * `--connection-name {connection}` the connection name to use (default is `django.db.DEFAULT_DB_ALIAS`)\n\n### migration_current_id\n\nShows the ID of the latest migration record in your `django_migration` table.\n\n```\n\u003e python manage.py migration_current_id\n18\n```\n\n18 is the ID of the latest record as shown above.\n\n#### Optional parameters:\n\n  * `--connection-name {connection}` the connection name to use (default is `django.db.DEFAULT_DB_ALIAS`)\n\n### migration_rollback\n\nRoll-back (unapply) previously applied migrations _after_ (but not including) the migration ID provided.\n\n```\n\u003e python manage.py migration_rollback 2\n```\n\nThe above will rollback migrations after `0001_initial` of the `auth` app (ID 2). The helper will \nfigure out and run the intermediate rollbacks for different Django apps (e.g. `sessions`, `auth`, `contenttypes`) \nto get us back to ID 2.\n\nIt will use the existing migration command (e.g. `python manage.py migrate ...`) for compatibility. There is no\n\"clever\" rewrite of anything.\n\nHere's what it runs:\n```\npython manage.py migrate sessions zero\nOperations to perform:\n  Unapply all migrations: sessions\nRunning migrations:\n  Rendering model states... DONE\n  Unapplying sessions.0001_initial... OK\n\npython manage.py migrate auth 0001_initial\nOperations to perform:\n  Target specific migration: 0001_initial, from auth\nRunning migrations:\n  Rendering model states... DONE\n  Unapplying auth.0012_alter_user_first_name_max_length... OK\n  Unapplying auth.0011_update_proxy_permissions... OK\n  Unapplying auth.0010_alter_group_name_max_length... OK\n  Unapplying auth.0009_alter_user_last_name_max_length... OK\n  Unapplying auth.0008_alter_user_username_max_length... OK\n  Unapplying auth.0007_alter_validators_add_error_messages... OK\n  Unapplying auth.0006_require_contenttypes_0002... OK\n  Unapplying auth.0005_alter_user_last_login_null... OK\n  Unapplying auth.0004_alter_user_username_opts... OK\n  Unapplying auth.0003_alter_user_email_max_length... OK\n  Unapplying auth.0002_alter_permission_name_max_length... OK\n\npython manage.py migrate contenttypes 0001_initial\nOperations to perform:\n  Target specific migration: 0001_initial, from contenttypes\nRunning migrations:\n  Rendering model states... DONE\n  Unapplying contenttypes.0002_remove_content_type_name... OK\n```\n\nNow, the migration state is where the latest migration record is ID 2:\n```\n\u003e python manage.py migration_records\n    ID Applied                           App Name\n     1 2024-12-06T18:15:03+0000 contenttypes 0001_initial\n     2 2024-12-06T18:15:03+0000         auth 0001_initial\n```\n\n#### Optional parameters:\n\n  * `--connection-name {connection}` the connection name to use (default is `django.db.DEFAULT_DB_ALIAS`)\n  * `--dry-run` will print the commands but will not actually run them\n  * `--migrate-cmd \u003ccommand to run migrations\u003e` sets the command to run migrations with. The command must accept \n    the app and migration name as the `{app}` and `{name}` placeholders, respectively.  \n    \n    For example:\n    \n    ```\n    --migrate-cmd \"pipenv run python manage.py migrate {app} {name}\" \n    ```\n    \n    can be used to have the command run migrations using `pipenv`.\n\n    For example:\n\n    ```\n    \u003e pipenv run python manage.py migration_rollback 0 --dry-run --migrate-cmd \"pipenv run python manage.py migrate {app} {name}\"\n    pipenv run python manage.py migrate sessions zero\n    pipenv run python manage.py migrate auth 0001_initial\n    pipenv run python manage.py migrate contenttypes 0001_initial\n    pipenv run python manage.py migrate admin zero\n    pipenv run python manage.py migrate auth zero\n    pipenv run python manage.py migrate contenttypes zero\n    ```\n\n### migration_delete\n\nDeletes an entry from Django's migration records. This command should be\nused only as a last resort to fix up migration records that cannot be rolled back. No migration up/down is performed; \nthe record is simply removed from `django_migrations`.\n\nNOTE also that migrations that depend on the record being deleted will be \"broken\" after the deletion, so this \ncommand should only be run on \"leaf\" migration records unless you plan to also delete other migration records that\ndepend on the one being deleted.\n\n```\npython manage.py migration_delete myapp 0003_some_migration\nConfirm deletion of myapp:0003_some_migration (yes or no): yes\n```\nThe command above deletes the migration `0003_some_migration` for the app `myapp` (after\ngetting confirmation).\n\nTo delete without confirmation, use the `--yes` option:\n```\npython manage.py migration_delete myapp 0003_some_migration --yes\n```\n\n#### Optional parameters:\n  * `--connection-name {connection}` the connection name to use (default is `django.db.DEFAULT_DB_ALIAS`)\n  * `--yes` will proceed to deleting the record without asking for confirmation\n\n\n## Ideas for automation\n\nHere's an idea for automating the deployment of your Django app using these utilities:\n\n* Deploy new code\n* Run `migration_current_id` and capture the current ID\n* Run migration normally\n* Run your automated tests normally\n  * If tests pass, you're done!\n  * If tests fail, and you need to rollback, run\n  `migration_rollback \u003ccaptured ID\u003e`\n  \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbluedenim%2Fvmigration-helper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbluedenim%2Fvmigration-helper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbluedenim%2Fvmigration-helper/lists"}