Reputation:
I'm a beginner of Python and Flask. I was going through Flask tutorial up to "Define and Access the Database" section.
Wrote up all codes, saved, and did below on Windows command prompt.
flask init-db
However, got received the error on the command prompt as follows.
AttributeError: 'ellipsis' object has no attribute 'teardown_appcontext'
I doublechecked the codes to confirm it's written exactly in a way that tutorial specifies and it actually worked fine until the previous section. Searched through Stackoverflows if there is any similar questions, but ended up not finding out a clear cause.
Any advises? Thank you very much for your support.
--Additions--
Thanks Joost. Here is what I did.
__init__.py
import os
from flask import Flask
def create_app(test_config=None):
# create and configure the app
app = Flask(__name__, instance_relative_config=True)
app.config.from_mapping(
SECRET_KEY='dev',
DATABASE=os.path.join(app.instance_path, 'flaskr.sqlite'),
)
if test_config is None:
# Load the instance config, if it exists, when not testing
app.config.from_pyfile('config.py', silent=True)
else:
# Load the test config if passed in
app.config.from_mapping(test_config)
# ensure the instance floder exists
try:
os.makedirs(app.instance_path)
except OSError:
pass
# a simple page that says hello
@app.route('/hello')
def hello():
return 'Hello, World!'
def create_app():
app = ...
# existing code omitted
from . import db
db.init_app(app)
return app
db.py
import sqlite3
import click
from flask import current_app, g
from flask.cli import with_appcontext
def get_db():
if 'db' not in g:
g.db = sqlite3.connect(
current_app.config['DATABASE'],
detect_types=sqlite3.PARSE_DECLTYPES
)
g.db.row_factory = sqlite3.Row
return g.db
def close_db(e=None):
db = g.pop('db', None)
if db is not None:
db.close()
def init_db():
db = get_db()
with current_app.open_resource('schema.sql') as f:
db.executescript(f.read().decode('utf8'))
@click.command('init-db')
@with_appcontext
def init_db_command():
"""Clear the exisitng data and create new tables."""
init_db()
click.echo('Initialized the database.')
def init_app(app):
app.teardown_appcontext(close_db)
app.cli.add_command(init_db_command)
schema.sql
DROP TABLE IF EXISTS user;
DROP TABLE IF EXISTS post;
CREATE TABLE user (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
password TEXT NOT NULL
);
CREATE TABLE post (
id INTEGER PRIMARY KEY AUTOINCREMENT,
author_id INTEGER NOT NULL,
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
title TEXT NOT NULL,
body TEXT NOT NULL,
FOREIGN KEY (author_id) REFERENCES user (id)
);
And finally I did on the command prompt:
set FLASK_APP=flaskr
set FLASK_ENV=development
flask init-db
However it returned like this.
Any advises? Thank you very much.
Upvotes: 5
Views: 5488
Reputation: 333
you don't replace the existing code with the new proposed one, but you add to it,
so for example :
def create_app():
app = ...
# existing code omitted
from . import db
db.init_app(app)
return app
should be translated in your code by adding the two new lines :
from . import db
db.init_app(app)
to what's already there so far in the function, just before the last line.
return app
which should translate as other answers mentioned :
def create_app(test_config=None):
# create and configure the app
app = Flask(__name__, instance_relative_config=True)
app.config.from_mapping(
SECRET_KEY='dev',
DATABASE=os.path.join(app.instance_path, 'flaskr.sqlite'),
)
if test_config is None:
# Load the instance config, if it exists, when not testing
app.config.from_pyfile('config.py', silent=True)
else:
# Load the test config if passed in
app.config.from_mapping(test_config)
# ensure the instance floder exists
try:
os.makedirs(app.instance_path)
except OSError:
pass
# a simple page that says hello
@app.route('/hello')
def hello():
return 'Hello, World!'
from . import db
db.init_app(app)
return app
Upvotes: 0
Reputation: 51
You defined create_app()
twice. To solve your problem, make the following change in your __init__.py
files:
import os
from flask import Flask
def create_app(test_config=None):
""" Application factory function """
# create and configure the app
app = Flask(__name__, instance_relative_config=True)
app.config.from_mapping(
SECRET_KEY='dev',
DATABASE=os.path.join(app.instance_path, 'flaskr.sqlite'),
)
if test_config is None:
# load the instance config, if it exists, when not testing
app.config.from_pyfile('config.py', silent=True)
else:
# load the test config if passed in
app.config.from_mapping(test_config)
# ensure the instance folder exists
try:
os.makedirs(app.instance_path)
except OSError:
pass
# a simple page that says hello
@app.route('/hello')
def hello():
return 'Hello, World! Now We are Introducing Mr. Narendra Singh Parihar.THE BOSS !!'
from . import db
db.init_app(app)
return app
Upvotes: 5
Reputation: 121
Actually the problem is in your init.py I removed the second create_app() from your init file and edited it like below remember the app factory need to know where your db.py is while creating the app
import os
from flask import Flask
def create_app(test_config=None):
# create and configure the app
app = Flask(__name__, instance_relative_config=True)
app.config.from_mapping(
SECRET_KEY='dev',
DATABASE=os.path.join(app.instance_path, 'flaskr.sqlite'),
)
if test_config is None:
# Load the instance config, if it exists, when not testing
app.config.from_pyfile('config.py', silent=True)
else:
# Load the test config if passed in
app.config.from_mapping(test_config)
# ensure the instance floder exists
try:
os.makedirs(app.instance_path)
except OSError:
pass
# a simple page that says hello
@app.route('/hello')
def hello():
return 'Hello, World!'
from . import db
db.init_app(app)
return app
Upvotes: 0