Hi Miguel!
I'm attempting to use your flask-migrate CLI tool as per your tutorial.
Issue:
Running flask db init from the terminal fails with error:
File "/home/[replaced]/.local/lib/python3.5/site-packages/flask_migrate/__init__.py", line 109, in init
directory = current_app.extensions['migrate'].directory
KeyError: 'migrate'
Desired result:
flask db init should create the database (sqlite) and initialize database tables from all models.
Context:
FLASK_APP='run.py', where run.py does the import of 'app' and 'db' from (myapp)/__init__.pyapp = Flask(APP_NAME) in run.pydb = SQLAlchemy(app) in run.pySpeculative analysis:
It seems that current_app.extensions is not somehow being populated with a desired key migrate, which I assume refers to your Flask extension.
Where/how is that supposed to happen?
There may be steps here I've missed or required parameters I'm unaware of.
Can you point me in the right direction?
Thanks!
Hi fieldse.
Did you create a Migrate object?
I get the same error when trying flask db init without that object.
from flask import Flask
from config import Config
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
migrate = Migrate(app, db) # this
Yes, I think @utsushiiro is right, you did not initialize the Flask-Migrate extension by creating a Migrate object.
@utsushiiro You're a wizard. :smile:
@miguelgrinberg Correct, that was it.
Yeah, I had abstracted the migrate = Migrate(app, db) to a separate function.
Adding migrate = Migrate(app, db) into __init__.py resolved the issue. (I didn't realize this was necessary for the cli functionality and database initialization, assumed it was related only to database migrations afterwards.)
Running flask db init now works correctly:
Thanks guys!
Get the same error. migrate = Migrate(app, db) in __init__.py. What I'm doing wrong? My code
All Traceback:
Traceback (most recent call last):
File "/home/iliasit/flask_projects/news_site/venv/bin/flask", line 11, in
sys.exit(main())
File "/home/iliasit/flask_projects/news_site/venv/lib/python3.6/site-packages/flask/cli.py", line 894, in main
cli.main(args=args, prog_name=name)
File "/home/iliasit/flask_projects/news_site/venv/lib/python3.6/site-packages/flask/cli.py", line 557, in main
return super(FlaskGroup, self).main(args, *kwargs)
File "/home/iliasit/flask_projects/news_site/venv/lib/python3.6/site-packages/click/core.py", line 697, in main
rv = self.invoke(ctx)
File "/home/iliasit/flask_projects/news_site/venv/lib/python3.6/site-packages/click/core.py", line 1066, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/home/iliasit/flask_projects/news_site/venv/lib/python3.6/site-packages/click/core.py", line 1066, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/home/iliasit/flask_projects/news_site/venv/lib/python3.6/site-packages/click/core.py", line 895, in invoke
return ctx.invoke(self.callback, *ctx.params)
File "/home/iliasit/flask_projects/news_site/venv/lib/python3.6/site-packages/click/core.py", line 535, in invoke
return callback(args, *kwargs)
File "/home/iliasit/flask_projects/news_site/venv/lib/python3.6/site-packages/click/decorators.py", line 17, in new_func
return f(get_current_context(), *args, *kwargs)
File "/home/iliasit/flask_projects/news_site/venv/lib/python3.6/site-packages/flask/cli.py", line 412, in decorator
return __ctx.invoke(f, args, *kwargs)
File "/home/iliasit/flask_projects/news_site/venv/lib/python3.6/site-packages/click/core.py", line 535, in invoke
return callback(args, *kwargs)
File "/home/iliasit/flask_projects/news_site/venv/lib/python3.6/site-packages/flask_migrate/cli.py", line 31, in init
_init(directory, multidb)
File "/home/iliasit/flask_projects/news_site/venv/lib/python3.6/site-packages/flask_migrate/__init__.py", line 109, in init
directory = current_app.extensions['migrate'].directory
KeyError: 'migrate'
@Nerevarishe does it still do it if you remove the app.run() call in app/__init__.py. If you are going to use the Flask CLI you have to start the app with flask run, don't use app.run().
Fixed. Problem was in bad pyCharm deployment directory configuration. Because that i use default pyCharm flask project file that don't have migrate = Migrate(app, db). So, need to be more attentive.
And app.run() does not affect on db init process.
I am getting the same error when I us e CLI in flask db init. I have created the Migrate object in the __init__.py file. I also dont use app.run().
Thank you for your help
Please show your code
@malay95 if you project on Win Machine try to go with PowerShell to \venv foulder of Project, (install again all packadges (now we installing not for venv enviroment only) WTF and etc.).
then type: $env:FLASK_APP = "<main_file_where_app.run()>.py"
then use flask commands: flask db init
I have a manage.py in the project base directory, and init the migrations by run
python manage.py db init
Hello Miguel, Hello world! :-)
I'm following step by step the flask mega tutorial (great work btw.!), but I'm stuck on this exact same issue, despite having everything in place pertaining the migrate object in app/__init__.py it seems.
I need a second pair of eyes on my code :) I've looked everywhere already without success.
my code & stacktrace: https://www.strauss-engineering.ch/tmp/
@phstrauss this line in app/__init__.py:
migrate = Migrate(db, app)
should be:
migrate = Migrate(app, db)
Hello Miguel, Hello Everyone, I'm following step by step the flask mega tutorial (great work btw.!), Flask Migrate once worked for me, but I'm stuck on this exact same issue,
This is my code
__init__.py
from flask_migrate import Migrate, MigrateCommand
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flask_login import LoginManager
from flask_script import Manager
app=Flask(__name__)
app.config['TESTING'] = True
app.config['SECRET_KEY'] = '3915c865a309c2d8c9892e4f5095f270'
app.config['SQLAlCHEMY_DATABASE_URI'] ='sqlite:///site.db'
db = SQLAlchemy(app)
migrate = Migrate(app, db)
manager=Manager(app)
manager.add_command('db', MigrateCommand)
bcrypt = Bcrypt(app)
login_manager=LoginManager(app)
from flaskblog import routes, models
if __name__ == "__main__":
manager.run()
run.py
from flaskblog import app, db
from flaskblog.models import User, Post
if __name__ == '__main__':
app.run(debug=True)
routes.py
from flask import redirect, render_template, flash, url_for, request
from flaskblog import app, bcrypt, db
from flaskblog.forms import RegistrationForm, LoginForm
from flaskblog.models import User, Post
from flask_login import login_user
posts = [
{'author': 'Corey Schafer',
'Title': 'Blog post 1',
'Content': 'First Post Comment',
'date_posted':'31 March, 2020'
},
{
'author': 'Jane Doe',
'Title': 'Blog post 2',
'Content': 'Second Post Comment',
'date_posted': '31 March, 2020'
}
]
@app.route('/')
@app.route('/home')
def home():
return render_template('home.html', posts=posts)
@app.route('/about')
def about():
return render_template('about.html', title=about)
@app.route('/user/
def user(name):
return 'Hi, %s!
' %name
@app.route('/register', methods=['GET', 'POST'])
def register():
form = RegistrationForm()
if form.validate_on_submit():
hashed_password = bcrypt.generate_password_hash(form.password.data).decode('utf-8')
user = User(username=form.username.data, email=form.email.data, password=hashed_password)
db.session.add(user)
db.session.commit()
print(form.username.data, form.email.data)
flash('Your account has been created, you can now log in', 'success')
return redirect(url_for('login'))
return render_template('register.html', title='Register', form=form)
@app.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data).first()
if user and bcrypt.check_password_hash(user.password, form.password.data):
login_user(user, remember=form.remember.data)
return redirect(url_for('home'))
else:
flash('Login Unsuccessful, check email and password', 'danger')
return render_template('login.html', title='Login', form=form)
model.py
from datetime import datetime
from flaskblog import db, login_manager
from flask_login import UserMixin
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
class User(db.Model):
__tablename__ = 'User'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(20), unique=True, nullable=False, index=True)
email = db.Column(db.String(20), unique=True, nullable=False)
image_file = db.Column(db.String(120), nullable=False, default='default.jpg')
password = db.Column(db.String(70), nullable=False)
posts = db.relationship('Post', backref='author', lazy=True)
def __repr__(self):
return f"User('{self.username}', '{self.email}', '{self.image_file}')"
class Post(db.Model):
__tablename__ = 'Post'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(120), unique=True, nullable=False)
date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
content = db.Column(db.Text, nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('User.id'), nullable=False)
def __repr__(self):
return f"Post('{self.title}', '{self.date_posted}')"
forms.py
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, BooleanField, ValidationError
from wtforms.validators import DataRequired, length, Email, EqualTo
from flaskblog.models import User, Post
class RegistrationForm(FlaskForm):
username = StringField('Username',
validators=[DataRequired(), length(min=2, max=20)])
email = StringField('Email', validators=[DataRequired(), Email()])
password = PasswordField('Password', validators=[DataRequired()])
confirm_password = PasswordField('Confirm_password',
validators=[DataRequired(), EqualTo('password')])
submit = SubmitField('Sign Up')
def validate_username(self, username):
user = User.query.filter_by(username=username.data).first()
if user:
raise ValidationError('The username is taken, please choose another one')
def validate_email(self, email):
email = User.query.filter_by(email=email.data).first()
if email:
raise ValidationError('The email is taken, please choose another one')
class LoginForm(FlaskForm):
email = StringField('Email', validators=[DataRequired(), Email()])
password = PasswordField('Password', validators=[DataRequired()])
remember = BooleanField('Remember me')
submit = SubmitField('Login')
@Brightadekunle stack trace of the error?
Most helpful comment
Hi fieldse.
Did you create a Migrate object?
I get the same error when trying
flask db initwithout that object.