{"id":13806081,"url":"https://github.com/nickjj/flask-db","last_synced_at":"2025-10-15T16:20:28.529Z","repository":{"id":46330957,"uuid":"314389295","full_name":"nickjj/flask-db","owner":"nickjj","description":"A Flask CLI extension to help migrate and manage your SQL database.","archived":false,"fork":false,"pushed_at":"2024-12-07T18:38:28.000Z","size":184,"stargazers_count":76,"open_issues_count":4,"forks_count":6,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-04T04:56:00.497Z","etag":null,"topics":["alembic","database","flask","migrations","sqlalchemy"],"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/nickjj.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","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},"funding":{"github":"nickjj","custom":["https://www.paypal.me/nickjanetakis"]}},"created_at":"2020-11-19T22:54:34.000Z","updated_at":"2025-09-26T02:45:31.000Z","dependencies_parsed_at":"2025-06-06T10:11:03.577Z","dependency_job_id":"4fc782ca-a080-4d37-9146-a865026d57a5","html_url":"https://github.com/nickjj/flask-db","commit_stats":{"total_commits":50,"total_committers":1,"mean_commits":50.0,"dds":0.0,"last_synced_commit":"109199f8c4a01e923afd1fe6fac34624e48c4544"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/nickjj/flask-db","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickjj%2Fflask-db","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickjj%2Fflask-db/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickjj%2Fflask-db/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickjj%2Fflask-db/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nickjj","download_url":"https://codeload.github.com/nickjj/flask-db/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickjj%2Fflask-db/sbom","scorecard":{"id":685154,"data":{"date":"2025-08-11","repo":{"name":"github.com/nickjj/flask-db","commit":"f964ca1a45b4db0a13f3e1ba678048b91544d57f"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.4,"checks":[{"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 0/30 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":"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":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"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":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/ci.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":"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/ci.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/nickjj/flask-db/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/nickjj/flask-db/ci.yml/master?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/ci.yml:23","Warn: pipCommand not pinned by hash: .github/workflows/ci.yml:28","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 pipCommand 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":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"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":"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":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"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"}}]},"last_synced_at":"2025-08-22T00:33:57.312Z","repository_id":46330957,"created_at":"2025-08-22T00:33:57.312Z","updated_at":"2025-08-22T00:33:57.312Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279091833,"owners_count":26101593,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-15T02:00:07.814Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["alembic","database","flask","migrations","sqlalchemy"],"created_at":"2024-08-04T01:01:07.686Z","updated_at":"2025-10-15T16:20:28.478Z","avatar_url":"https://github.com/nickjj.png","language":"Python","funding_links":["https://github.com/sponsors/nickjj","https://www.paypal.me/nickjanetakis"],"categories":["Third-Party Extensions","Python"],"sub_categories":["Databases"],"readme":"# What is Flask-DB? ![CI](https://github.com/nickjj/flask-db/workflows/CI/badge.svg?branch=master)\n\nIt's a Flask CLI extension that helps you migrate, drop, create and seed your\nSQL database.\n\nAfter installing it you'll gain access to a `flask db` command that will give\nyou a few database management commands to use.\n\nFor the migrations it uses Alembic. Anything you can do with Alembic can be\ndone with this CLI extension. If you're wondering why you might want to use\nthis tool instead of Alembic directly or Flask-Migrate, [check out this FAQ\nitem](#differences-between-alembic-flask-migrate-flask-alembic-and-flask-db).\n\n## Table of contents\n\n- [Demo video](#demo-video)\n- [Installation](#installation)\n- [Ensuring the `db` command is available](#ensuring-the-db-command-is-available)\n- [Going over the `db` command and its sub-commands](#going-over-the-db-command-and-its-sub-commands)\n- [FAQ](#faq)\n  - [Differences between Alembic, Flask-Migrate, Flask-Alembic and Flask-DB](#differences-between-alembic-flask-migrate-flask-alembic-and-flask-db)\n  - [Migrating from using Alembic directly or Flask-Migrate](#migrating-from-using-alembic-directly-or-flask-migrate)\n  - [Is it safe to edit the files that `flask db init` created?](#is-it-safe-to-edit-the-files-that-flask-db-init-created)\n  - [Should I add migration the files to version control?](#should-i-add-the-migration-files-to-version-control)\n  - [I keep getting a module not found error when migrating](#i-keep-getting-a-module-not-found-error-when-migrating)\n- [About the Author](#about-the-author)\n\n## Demo video\n\nHere's a run down on how this extension works and how you can add it to your\nproject:\n\n[![Demo\nVideo](https://img.youtube.com/vi/iDTmyF5HZ0Y/0.jpg)](https://www.youtube.com/watch?v=iDTmyF5HZ0Y)\n\nIf you prefer reading instead of video this README file covers installing,\nconfiguring and using this extension too.\n\n## Installation\n\n`pip3 install Flask-DB`\n\nThat's it!\n\nThere's no need to even import or initialize anything in your Flask app because\nit's just a CLI command that gets added to your Flask app.\n\n*But if you're curious, a complete example Flask app can be found in the\n[tests/\ndirectory](https://github.com/nickjj/flask-db/tree/master/tests/example_app).*\n\n#### Requirements:\n\n- Python 3.6+\n- Flask 1.0+\n- SQLAlchemy 1.2+\n- Alembic 1.3+\n\n## Ensuring the `db` command is available and everything works\n\nYou'll want to at least set the `FLASK_APP` and `PYTHONPATH` environment\nvariables:\n\n```sh\n# Replace `hello.app` with your app's name.\nexport FLASK_APP=hello.app\n\n# Due to how Alembic works you'll want to set this to be able to migrate\n# your database. It would be expected that you run your migrate commands from\n# the root of your project (more on this migrate command later).\nexport PYTHONPATH=\".\"\n\nexport FLASK_DEBUG=true\n```\n\nThen run the `flask` binary to see its help menu:\n\n```sh\n\nUsage: flask [OPTIONS] COMMAND [ARGS]...\n\n  ...\n\nCommands:\n  db      Migrate and manage your SQL database.\n```\n\nIf all went as planned you should see the new `db` command added to your\nlist of commands.\n\n## Going over the `db` command and its sub-commands\n\nRunning `flask db --help` will produce this help menu:\n\n```sh\nUsage: flask db [OPTIONS] COMMAND [ARGS]...\n\n  Migrate and manage your SQL database.\n\nOptions:\n  --help  Show this message and exit.\n\nCommands:\n  init     Generate Alembic config files and seeds.py.\n  reset    Drop, create and seed your database (careful in production).\n  seed     Seed the database with your custom records.\n  migrate  Wrap the alembic CLI tool (defaults to running upgrade head).\n```\n\n### `init`\n\nIf you've ever used Alembic before, you'll be familiar with `alembic init`.  If\nyou've never used it before it creates an `alembic.ini` file in the root of\nyour project along with a few other Alembic files in a `yourappname/migrations`\ndirectory by default.\n\nYou can treat `flask db init` as a drop in replacement for `alembic init`.\n\n`flask db init` does something similar. The 4 main differences are:\n\n1. It defaults to `db/` instead of `yourappname/migrations`, but you can modify\n   this path by running `flask db init any/path/you/want`.\n\n2. It will create the same Alembic config files but it modifies them to be a\n   bit more generic and portable when it comes to finding your\n   `SQLALCHEMY_DATABASE_URI`.\n\n3. It also configures Alembic to support auto generating migrations in case you\n   want to use `revision --autogenerate` as a starting point for your\n   migrations (always review them afterwards!).\n\n4. It creates a `seeds.py` file in the same directory you initialized things to\n   (more on this soon).\n\n### `reset`\n\nCreates your database if it needs to be created along with doing a\n`db.drop_all()` and `db.create_all()`.  That is going to purge all of your\nexisting data and create any tables based on whatever SQLAlchemy models you\nhave.\n\nIt also automatically calls `flask db seed` for you (more on seeding soon).\n\n#### Options\n\n```\nOptions:\n  --with-testdb  Create a test DB in addition to your main DB?\n```\n\nIf you run `flask db reset --with-testdb` then a second database will also be\ncreated based on whatever your database name is from your\n`SQLALCHEMY_DATABASE_URI` along with appending `_test` to its name.\n\nFor example, if you had a db named `hello` and you used `--with-testdb` then\nyou would end up with both a `hello` and `hello_test` database. It's very\nuseful to have a dedicated test database so you don't clobber your dev data.\n\n#### When should you use this command?\n\nThat depends on the state of your project.\n\n##### Brand new project that you never deployed?\n\nThis is something you'll be running all the time in development as you change\nyour database models.\n\nIt's also something you'd typically run once in production the first time you\ndeploy your app. This will handle creating your database and syncing all of\nyour models as tables in your database.\n\n##### Deployed your app at least once?\n\nPurging all of your data isn't an option anymore. If you want to make database\nchanges you should be creating database migrations with `flask db migrate`,\nwhich is really running [Alembic](https://alembic.sqlalchemy.org/en/latest/)\ncommands behind the scenes. That is the official migration tool created by the\nsame folks who made SQLAlchemy.\n\nWe'll go over the `migrate` command shortly.\n\n### `seed`\n\nSeeds your database with initial records of your choosing.\n\nWhen you set up your app for the first time in production chances are you'll\nwant certain things to be created in your database. At the very least probably\nan initial admin user.\n\nThis command will read in and execute a `seeds.py` file that exists in the\ndirectory that you initialized with `flask db init`. By default that will be\n`db/seeds.py`.\n\nIf you supplied a custom init path you must change your seeds path. You can do\nthat by setting `FLASK_DB_SEEDS_PATH` in your app's config. For example if you\nran `flask db init yourappname/migrations` then you'd set `FLASK_DB_SEEDS_PATH\n= \"yourappname/migrations/seeds.py\"`.\n\nAs for the seeds file, you have full control over what you want to do. You can\nadd whatever records that make sense for your app or keep the file empty to not\nseed anything. It's simply a file that's going to get called and execute any\ncode you've placed into it.\n\n#### Best practices for seeding data\n\nIt's a good idea to make your seeds file idempotent. Meaning, if you run it 1\ntime or 100 times the end result should be the same. The [example in the seeds\nfile](https://github.com/nickjj/flask-db/tree/master/tests/example_app/db/seeds.py)\nis idempotent because it first checks to see if the user exists before adding\nit.\n\nIf the user exists, it skips trying to create the user. Without this check then\nyou would end up getting a database uniqueness constraint error on the 2nd run.\nThat's because the example test app added a [unique index on the\nusername](https://github.com/nickjj/flask-db/blob/master/tests/example_app/example/app.py#L20).\n\n### `migrate`\n\nThe `flask db migrate` command is an alias to the `alembic` command.\n\nHere's a few examples:\n\n```sh\nflask db migrate revision -m \"hi\" -\u003e alembic revision -m \"hi\"\nflask db migrate upgrade head     -\u003e alembic upgrade head\nflask db migrate                  -\u003e alembic upgrade head (convenience shortcut)\nflask db migrate -h               -\u003e alembic -h\n```\n\nEvery possible thing you can run with `alembic` can now be run with `flask db\nmigrate`. That means you can follow Alembic's tutorials and documentation\nexactly.\n\nYou can still use alembic commands directly if you prefer. I just liked the\nidea of having all db related commands under the same namespace and the `flask\ndb migrate` shortcut is handy.\n\nYou'll also be happy to hear that this tool doesn't hard code all of Alembic's\ncommands, options and arguments with hundreds of lines of code. What that means\nis, as Alembic's CLI API changes in the future this `flask db migrate` command\nwill continue to work with all future versions.\n\nAll it does is forward everything you pass in, similar to `$@` in Bash.\n\nThat's also why you need to run `-h` to get Alembic's help menu instead of\n`--help` because that will ultimately call the internal help menu for `flask db\nmigrate`.\n\n## FAQ\n\n### Differences between Alembic, Flask-Migrate, Flask-Alembic and Flask-DB\n\nHere's the breakdown of these tools:\n\n*Disclaimer: I'm not here to crap on the work of others, I'm simply giving my\nopinion on why I chose to create Flask-DB and don't use the Alembic CLI\ndirectly, Flask-Migrate or Flask-Alembic.*\n\n#### Alembic\n\nThe official database migration tool for SQLAlchemy written by the same team\nwho made SQLAlchemy.\n\nAlembic generates a bunch of config files and often times you'll want to go in\nand edit them to be more dynamic for finding your `SQLALCHEMY_DATABASE_URI` as\nwell as adding a few useful opinions that you'll want in 99.999% of apps.\n\nIt got a little tedious making these adjustments in every app.\n\nBesides having config files, Alembic also includes an `alembic` CLI tool to\ninteract with your database such as generating migration files, executing\nmigrations and more. This tool is fantastic.\n\nFlask-Migrate, Flask-Alembic and Flask-DB all use Alembic behind the scenes,\nbut they are implemented in much different ways.\n\n#### Flask-Migrate\n\nAt the time of writing this FAQ item (November 2020) the approach this library\ntakes it to import the Alembic Python module and then build a custom CLI tool\nwith various commands, options and arguments that lets you access functionality\nthat Alembic already provides.\n\nIn my opinion this is very error prone because Alembic already has a battle\nhardened `alembic` CLI tool that comes part of the Alembic Python package. You\nget this out of the box when you `pip3 install alembic`. Flask-Migrate is error\nprone because it has hundreds upon hundreds of lines of code re-creating the\nsame `alembic` CLI tool that already exists.\n\nAlso it's not future proof because if Alembic decides to change its API or add\nnew features now you'll need to wait for Flask-Migrate to update all of its\ncode and push a new release instead of just grabbing the new `alembic` package.\n\nFor example, here's a tiny snippet of code from [Flask-Migrate's `migrate`\ncommand](https://github.com/miguelgrinberg/Flask-Migrate/blob/4887bd53bc08f10087fe27a4a7d9fe853031cdcf/flask_migrate/cli.py#L64=L90):\n\n```py\n@db.command()\n@click.option('-d', '--directory', default=None,\n              help=('Migration script directory (default is \"migrations\")'))\n@click.option('-m', '--message', default=None, help='Revision message')\n@click.option('--sql', is_flag=True,\n              help=('Don\\'t emit SQL to database - dump to standard output '\n                    'instead'))\n@click.option('--head', default='head',\n              help=('Specify head revision or \u003cbranchname\u003e@head to base new '\n                    'revision on'))\n@click.option('--splice', is_flag=True,\n              help=('Allow a non-head revision as the \"head\" to splice onto'))\n@click.option('--branch-label', default=None,\n              help=('Specify a branch label to apply to the new revision'))\n@click.option('--version-path', default=None,\n              help=('Specify specific path from config for version file'))\n@click.option('--rev-id', default=None,\n              help=('Specify a hardcoded revision id instead of generating '\n                    'one'))\n@click.option('-x', '--x-arg', multiple=True,\n              help='Additional arguments consumed by custom env.py scripts')\n@with_appcontext\ndef migrate(directory, message, sql, head, splice, branch_label, version_path,\n            rev_id, x_arg):\n    \"\"\"Autogenerate a new revision file (Alias for 'revision --autogenerate')\"\"\"\n    _migrate(directory, message, sql, head, splice, branch_label, version_path,\n             rev_id, x_arg)\n```\n\nNeedless to say when you do this for a dozen commands with many dozens of flags\nit's easy for errors to slip by.\n\nAnother thing is Flask-Migrate's `flask db migrate` command defaults to using\nauto-generated migrations. This feature is useful for speeding up the process\nof creating migration files but Alembic doesn't detect everything which can be\nvery confusing if you're not aware of [Alembic's limitations with\nauto-generate](https://alembic.sqlalchemy.org/en/latest/autogenerate.html#what-does-autogenerate-detect-and-what-does-it-not-detect).\n\nThere's also no help for doing things like resetting and seeding your database.\nIt's a tool exclusively designed for running database migrations with Alembic.\n\n#### Flask-Alembic\n\nThis tool internally imports the Alembic Python library and creates its own CLI\naround that. It's similar to Flask-Migrate in that regard but not of all of the\ncommands are API compatible with the `alembic` CLI.\n\nFor example, here's a snippet from [Flask-Alembic's `revision`\ncommand](https://github.com/davidism/flask-alembic/blob/c8f202d4522123760a52865b6d3806470fa396e9/src/flask_alembic/cli/script.py#L94-L117):\n\n```py\n@manager.option(\"message\")\n@manager.option(\"--empty\", action=\"store_true\", help=\"Create empty script.\")\n@manager.option(\n    \"-b\", \"--branch\", default=\"default\", help=\"Use this independent branch name.\"\n)\n@manager.option(\n    \"-p\",\n    \"--parent\",\n    default=\"head\",\n    type=str.split,\n    help=\"Parent revision(s) of this revision.\",\n)\n@manager.option(\"--splice\", action=\"store_true\", help=\"Allow non-head parent revision.\")\n@manager.option(\n    \"-d\", \"--depend\", type=str.split, help=\"Revision(s) this revision depends on.\"\n)\n@manager.option(\n    \"-l\", \"--label\", type=str.split, help=\"Label(s) to apply to the revision.\"\n)\n@manager.option(\"--path\", help=\"Where to store the revision.\")\ndef revision(message, empty, branch, parent, splice, depend, label, path):\n    \"\"\"Create new migration.\"\"\"\n\n    base.revision(message, empty, branch, parent, splice, depend, label, path)\n```\n\nIt's missing a few flags that `alembic revision --help` would provide you.\nPersonally I'd rather use the official `alembic` CLI since it already exists\nand it's very well tested and developed by the Alembic team.\n\nAlso, it doesn't handle `alembic init` or have its own form of `init` so you're\nleft having to generate and modify the default Alembic config files in every\nproject.\n\nLike Flask-Migrate it also doesn't help with resetting and seeding your\ndatabase.\n\n#### Flask-DB\n\nFlask-DB is more than a database migration tool that wraps Alembic. It also\nincludes being able to reset and seed your database.\n\nUnlike using Alembic directly for the `init` command it modernizes and applies\na few opinions to the default Alembic configuration so that you can usually use\nthese files as is in your projects without modification. If you do need to\nmodify them, that's ok. They are generated in your project which you can edit.\n\nAs for migrations, it aliases the `alembic` CLI but it does it with about 5\nlines of code for everything rather than hundreds of lines of code. The lines\nof code aren't that important, it's mainly being less error prone and more\nfuture proof. It's taking advantage of the well tested `alembic` CLI tool that\nAlembic gave us.\n\nThat means if a future version of Alembic comes out that adds new features it\nwill automatically work with Flask-DB without having to update Flask-DB. All\nyou would do is upgrade your `alembic` package version and you're done.\n\nSince about 2015 I used to create my own `db` CLI command in each project which\nhandled resetting and seeding the database. Then I used the `alembic` CLI\ndirectly.  Anyone who has taken my [Build a SAAS App with Flask\ncourse](https://buildasaasappwithflask.com/?utm_source=github\u0026utm_medium=flaskdb\u0026utm_campaign=readme)\nis probably used to that. \n\nFlask-DB was created as an improvement to that work flow. Now it's as easy as\npip installing this tool and you're good to go with ready to go configs, a\nconsistent Alembic CLI API and the added reset + seed functionality.\n\n### Migrating from using Alembic directly or Flask-Migrate\n\nThere's 2 ways to go about this and it's up to you on which one to pick.\n\n*In both cases if you're using Flask-Migrate you'll want to `pip3 uninstall\nFlask-Migrate` since both Flask-DB and Flask-Migrate add a `db` command to\nFlask.*\n\n#### 1. Keep all of your existing Alembic files and directory structure\n\nBy default Alembic (and therefore Flask-Migrate) will put a `migrations/`\ndirectory inside of your application.\n\nYou can still keep your files there with Flask-DB too. You'll just need to\nconfigure `FLASK_DB_SEEDS_PATH` to be `yourappname/migrations/seeds.py`. You'll\nalso want to create that file manually (keeping it empty for now is ok).\n\nThat's pretty much all you need to do.\n\nIf you're using Flask-Migrate, Flask-DB has more up to date Alembic config\nfiles so you may still want to initialize a new directory with `flask db init`.\nThen you can pick and choose what you want to keep from your existing Alembic\nconfigs and what's been generated by the Flask-DB's init command.\n\n#### 2. Initialize a new directory and move your `versions/` into it (recommended)\n\nThe other option would be to run `flask db init` and let it create a `db/`\ndirectory in the root of your project.\n\nChances are you already have an `alembic.ini` file. The init command will\nrecognize that and create an `alembic.ini.new` file to avoid clobbering your\nexisting file. Then you can delete your old `alembic.init` file and `mv\nalembic.ini.new alembic.ini` to use the new one.\n\nFrom here you can take your existing migration files in your old `versions/`\ndirectory and move them into `db/versions/`. At this point you can delete your\nold `yourappname/migrations/` directory as long as you haven't done any drastic\ncustomizations to your alembic related config files.\n\nIf you've done a bunch of custom configurations that's ok, you can manually\nmerge in your changes. You're free to edit these files however you see fit.\n\n### Is it safe to edit the files that `flask db init` created?\n\nAbsolutely. The init command is there to set up the initial files that Alembic\nexpects to be created, along with adding things like the `seeds.py` file too.\n\nThe Alembic files will likely be good to go for you without having to modify\nanything but you can change them however you see fit. One thing worth\nmentioning is if your app factory function isn't called `create_app` you will\nwant to change the `db/env.py` file's import near the top to use your custom\nfactory function's name instead.\n\nYou also have free reign to add whatever you want to the `seeds.py` file. By\ndefault it generates a couple of comments to help show how you can use it\ngenerate an initial user in your database.\n\n### Should I add the migration files to version control?\n\nYes! Your `alembic.ini` along with your entire `db/` directory (default `init`\ndirectory) including the `versions/*` files should all be commit to version\ncontrol.\n\nThis way you can develop and test your migrations locally on your dev box, make\nsure everything works then commit and push your code. At that point you can run\nyour migrations in CI and ultimately in production with confidence that it all\nworks.\n\n### I keep getting a module not found error when migrating\n\nYou might have seen this error: `ModuleNotFoundError: No module named\n'yourappname'`\n\nChances are you haven't set your `PYTHONPATH=\".\"` env variable. If you're using\nDocker you can set this in your Dockerfile and you'll be good to go. Here's a\nworking example from my [Build a SAAS App with\nFlask](https://github.com/nickjj/build-a-saas-app-with-flask/blob/f1ccd0aaae39cce89e53989dd498d97e1de95820/Dockerfile#L55)\nrepo.\n\nIf you're not using Docker please make sure that your `PYTHONPATH` environment\nvariable is available on your shell by doing any of the things below:\n\n- `export PYTHONPATH=\".\"` in your terminal and now it'll be set until you close your terminal\n- Create a `.env` file and then run `source .env` and it'll be set until you close your terminal\n- Run `PYTHONPATH=\".\" flask db migrate` instead of `flask db migrate`\n\nIn all cases it would be expected that you run the `flask db migrate` command\nfrom the root of your project. That's the same directory as where your\n`alembic.ini` file is located.\n\n## About the author\n\n- Nick Janetakis | \u003chttps://nickjanetakis.com\u003e | [@nickjanetakis](https://twitter.com/nickjanetakis)\n\nIf you're interested in learning Flask I have a 20+ hour video course called\n[Build a SAAS App with\nFlask](https://buildasaasappwithflask.com/?utm_source=github\u0026utm_medium=flaskdb\u0026utm_campaign=readme).\nIt's a course where we build a real world SAAS app. Everything about the course\nand demo videos of what we build is on the site linked above.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnickjj%2Fflask-db","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnickjj%2Fflask-db","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnickjj%2Fflask-db/lists"}