I followed the tutorial at https://flask.palletsprojects.com/en/2.0.x/tutorial/factory/ and successfully created the project there. I then tried to apply this to my new project and I'm getting hung up right away. The database schema doesn't seem to get read at any point. At other points in the code I tried to print the tables and got an empty list. Here are the relevant chunks in the code where it should happen.
__init__.py:
import os
from flask import Flask
def create_app(test_config=None):
app = Flask(__name__, instance_relative_config=True)
app.config.from_mapping(
SECRET_KEY='dev',
DATABASE=os.path.join(app.instance_path, 'projectdb.sqlite')
)
if test_config is None:
app.config.from_pyfile('config.py', silent=True)
else:
app.config.from_mapping(test_config)
try:
os.makedirs(app.instance_path)
except OSError:
pass
from . import db
db.init_app(app)
from . import auth
app.register_blueprint(auth.bp)
print("App created")
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():
init_db()
click.echo('Initialized the database.')
def init_app(app):
app.teardown_appcontext(close_db)
app.cli.add_command(init_db_command)
auth.py:
import functools
from flask import (
Blueprint, flash, g, redirect, render_template, request, session, url_for
)
from werkzeug.security import check_password_hash, generate_password_hash
from ldmt.db import get_db
bp = Blueprint('auth', __name__, url_prefix='/auth')
@bp.route('/login', methods=('GET', 'POST'))
def login():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
db = get_db()
error = None
user = db.execute(
'SELECT * FROM user WHERE username = ?', (username,)
).fetchone()
if user is None:
error = 'invalid username.'
elif not check_password_hash(user['password'], password):
error = 'incorrect password.'
if error is None:
session.clear()
session['user_id'] = user['id']
return redirect(url_for('index'))
flash(error)
return render_template('auth/login.html')
@bp.before_app_request
def load_logged_in_user():
user_id = session.get('user_id')
if user_id is None:
g.user = None
else:
g.user = get_db().execute(
'SELECT * FROM user WHERE id = ?', (user_id,)
).fetchone()
@bp.route('/logout')
def logout():
session.clear()
return redirect(url_for('auth.login'))
def login_required(view):
@functools.wraps(view)
def wrapped_view(**kwargs):
if g.user is None:
return redirect(url_for('auth.login'))
return view(**kwargs)
return wrapped_view
schema.sql:
DROP TABLE IF EXISTS user;
CREATE TABLE user (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
password TEXT NOT NULL
);
The problem happens when I try to login. Nothing has been added to the database so I expect an error that that user is not found, but the error I get is sqlite3.OperationalError: no such table: user
I can also confirm that the .sqlite file is created but empty.
get_db(). It's hard to help when there's no code to show the flow of the script, what calls what or anything like that. Also what command are you running to start this script?flask run. I didn't enter any extra commands with the tutorial either. The process is mimicking flask.palletsprojects.com/en/2.0.x/tutorial/database Tracing it,__init__.pyis supposed to call db.init_app(): "app.cli.add_command() adds a new command that can be called with the flask command. Import and call this function from the factory. Place the new code at the end of the factory function before returning the app."