-
-
Notifications
You must be signed in to change notification settings - Fork 900
CLI support #520
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CLI support #520
Conversation
| try: | ||
| from flask.cli import with_appcontext | ||
| except ImportError: | ||
| from flask_cli import with_appcontext |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO it'd be better to just drop support for anclient flask versions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Flask-CLI supports Flask 0.10, and CLI support was added to Flask in 0.11. Flask 0.10 was released in June 2013, while Flask 0.11 was released in June 2016. Three years is hardly ancient history, even in software development.
Besides, the cost of supporting Flask-CLI is so low. Is it really a problem to keep this in?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, just my opinion :) And I'd say using a 3y old version from a 0.x line is kind of ancient.
flask_sqlalchemy/cli.py
Outdated
| @db.command('drop') | ||
| @click.option('--bind', default='__all__') | ||
| @click.confirmation_option(prompt=( | ||
| "This will destroy all the data in your database. " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would go a step further and completely disallow running this unless the app is in debug mode. It's something you pretty much never need outside development.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see where you're coming from -- this is a potential footgun, and we should be careful with it. At the same time, I can imagine circumstances where it has a use with debug mode turned off. For example, it's reasonable to have an automated test flow where the code is automatically checked out, setup, run, and torn down, and where debug mode is specifically turned off, in order to make the test more consistent with a production environment. There's no reason not to support that flow, and I think that having a confirmation step will deter most human error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can always call it with FLASK_DEBUG=1 in that case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Besides that, creating/dropping database tables for tests should usually be part of the test setup (e.g. pytest fixtures).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm talking about a testing flow that isn't necessarily in Python. For example, a Jenkins worker that sets up the codebase and then runs Selenium tests. That sort of scenario would generally be scripted in bash, not in Python.
I hadn't thought about FLASK_DEBUG=1 -- but if anything, that makes me even less keen to make this change. The confirmation option can be bypassed by running flask db drop --yes -- what makes you think it's any more difficult to just run FLASK_DEBUG=1 flask db drop --yes instead?
I'm all for avoiding footguns, but this smacks of child-proofing that is too easily disabled to be useful. I believe we should make sure that people are aware of the risks of what they're doing (hence the confirmation option), and then trust that they're smart enough to do the right thing.
|
I don't know how I feel about this. I'd rather people use Flask-Alembic or Flask-Migrate to manage creating/dropping tables. Also, using |
|
FWIW, even when using Flask-Migrate and Alembic it's usually a good idea to let SQLAlchemy deal with creating the initial revision. However, I think adding support to call |
|
@davidism: It shouldn't be too hard to have Flask-Alembic or Flask-Migrate add commands to the try:
from flask_sqlalchemy.cli import db
except ImportError:
@click.group()
def db():
pass
@db.command()
def migrate():
# implementation here... |
|
@davidism: I created an example repository that demonstrates how I think we could resolve this problem. It turns out that if you set up both Flask-SQLAlchemy and Flask-Alembic, and they both try to create a command group named Example repo: https://github.com/singingwolfboy/flask-sqlalchemy-alembic-test Can you take a look, and tell me what you think of this approach? |
|
But is that order guaranteed? There's no requirement that Flask-Alembic/Migrate is initialized after Flask-SQLAlchemy. |
|
It kind of makes sense to initialize Flask-SQLAlchemy before an extension that depends on it. Doesn't seem to be a hard requirement though (at least not when using |
|
I guarantee we will get users doing it in the "wrong" order unless Flask-Alembic/Migrate enforce it in While I recognize that create/drop commands would be useful for quick apps, for pretty much any serious development I want to encourage people to use Alembic to manage their database. This is partially just a documentation issue. We should have a page that says "create your tables. If you're doing this a lot, use Alembic to manage migrations." @miguelgrinberg any comments? |
|
Keep in mind that "quick apps" are a major use case for Flask. Many people who want database support in Flask aren't interested in setting up database migrations, because it's too much overhead for what they're looking for. |
|
The argument that this is useful for quick apps isn't strong in my opinion. A quick app will likely use a SQLite database. If I need to drop all tables in a SQLite database, I delete the database file, as that is fully accurate, unlike I guess I can see a benefit in having a |
|
Would you be willing to update Flask-Migrate so it ensures it's initialized after Flask-SQLAlchemy? That way we guarantee the correct commands are used. |
|
@miguelgrinberg I hadn't thought about that argument against |
|
@miguelgrinberg I'm going with def init_app(self, app):
if 'sqlalchemy' not in app.extensions:
raise RuntimeError('you need to initialize Flask-SQLAlchemy first')and adding a Although overriding the |
|
Don't some people use SQLAlchemy directly, without using the Flask-SQLAlchemy extension? Do you think that any of them use Flask-Alembic or Flask-Migrate? If so, they probably won't be happy with a mandatory dependency on Flask-SQLAlchemy (although it's easy enough to work around, just by shoving some random object in |
|
Not sure about Flask-Migrate, Flask-Alembic only works if Flask-SQLAlchemy is installed, I don't currently support other setups. |
|
@davidism If Flask-Alembic already has a hard dependency on Flask-SQLAlchemy, then enforcing the ordering is definitely a good idea. |
|
Flask-Migrate also requires Flask-SQLAlchemy. @davidism is it necessary to force the init of Flask-SQLalchemy first? Importing the |
|
Either way will work, neither requires updating Flask-SQLAlchemy. |
|
I pushed a commit to remove the |
|
@singingwolfboy The Thanks for the PR ;) it seems quite handy! |
|
The pull request is now passing tests. Is there anything else that needs to be done here, or can this be merged? |
|
Bump here? Also, needs rebase :) |
Not clear that it's actually _useful_
|
@gaffney thanks for the reminder! I've rebased the pull request. |
|
Note that Travis CI is only failing this pull request because it's trying to build on Python 2.6, which SQLAlchemy no longer supports. #621 should resolve this issue. |
|
Closing for now, this is too outdated. Opened #1090 to summarize and discuss a bit more. |
Basic CLI support for Flask-SQLAlchemy, modeled after the CLI support in Flask-Security. Supports the following command:
flask db create