Good day,
I am new to Flask. In the midst of developing my “to do list” app, I wanted to modify detail of “email” column in databases.py.
Below is databases.py
:
<code>from flask_sqlalchemy import SQLAlchemy
# Create SQLAlchemy instance
id = db.Column(db.Integer, primary_key=True)
first_name = db.Column(db.String(10), unique=False, nullable=False)
last_name = db.Column(db.String(10), unique=False, nullable=False)
email = db.Column(db.String(20), unique=True, nullable=False)
password = db.Column(db.String(12), nullable=True)
<code>from flask_sqlalchemy import SQLAlchemy
# Create SQLAlchemy instance
db = SQLAlchemy()
# Define database models
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
first_name = db.Column(db.String(10), unique=False, nullable=False)
last_name = db.Column(db.String(10), unique=False, nullable=False)
email = db.Column(db.String(20), unique=True, nullable=False)
password = db.Column(db.String(12), nullable=True)
</code>
from flask_sqlalchemy import SQLAlchemy
# Create SQLAlchemy instance
db = SQLAlchemy()
# Define database models
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
first_name = db.Column(db.String(10), unique=False, nullable=False)
last_name = db.Column(db.String(10), unique=False, nullable=False)
email = db.Column(db.String(20), unique=True, nullable=False)
password = db.Column(db.String(12), nullable=True)
My app requires user to login with email and password hence I believe “email” should be unique. So I changed the unique
parameter from False to True.
Based on Flask-Migrate documentation, I should execute commands flask db migrate -m "brief description"
and flask db upgrade
each time the database models change.
However, I encountered error message RuntimeError: A 'SQLAlchemy' instance has already been registered on this Flask app. Import and use that instance instead.
when I execute commands flask --debug run
/ flask db migrate
.
Below is app.py
:
<code>from flask import Flask, render_template, request, redirect, url_for, flash, get_flashed_messages, session
from email_validator import validate_email, EmailNotValidError
from flask_bootstrap import Bootstrap5
from flask_migrate import Migrate
from flask_session import Session
# Create instance for Bootstrap 5
# Create session instance
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///notes.db'
app.config['SESSION_TYPE'] = 'sqlalchemy'
app.config['SESSION_PERMANENT'] = False
user_session.init_app(app)
from databases import db, User
1. execute command in terminal for very first time => Flask --debug run
2. execute command in terminal => flask db init
3. execute command in terminal => flask db migrate -m "Initial migration"
4. execute command in terminal => flask db upgrade
migrate = Migrate(app, db)
app.secret_key = secrets.token_hex(8)
# initiate Bootstrap5 for the app
from forms import new_user, login_user
@app.route('/register', methods=['GET', 'POST'])
register_user = new_user()
if register_user.validate_on_submit():
first_name = request.form.get('first_name'),
last_name = request.form.get('last_name'),
email = request.form.get('email'),
password = request.form.get('password')
return redirect(url_for('login'))
return render_template('new_user.html', form=register_user)
@app.route('/login', methods=['GET', 'POST'])
user_login = login_user()
if user_login.validate_on_submit():
email_input = request.form.get('email')
password_input = request.form.get('password')
checkbox = request.form.get('checkbox')
user_record = db.session().execute(
db.select(User).filter_by(email=email_input)
invalid_email = f"Invalid email !!"
return render_template('login.html', form=user_login, invalid_email=invalid_email)
elif user_record.password != password_input:
invalid_password = f"Wrong password !!"
return render_template('login.html', form=user_login, invalid_password=invalid_password)
user_session['email'] = email_input if checkbox else None
return redirect(url_for('profile', id=user_record.id))
return render_template('login.html', form=user_login)
@app.route('/profile/<int:id>')
if user_session.get('email'):
user_record = db.session().execute(
db.select(User).filter_by(id=id)
flash(message=f"Welcome back, { user_record.first_name }", category='info')
return render_template('user_homepage.html', user=user_record)
return redirect(url_for('login'))
<code>from flask import Flask, render_template, request, redirect, url_for, flash, get_flashed_messages, session
from email_validator import validate_email, EmailNotValidError
import secrets
from flask_bootstrap import Bootstrap5
from flask_migrate import Migrate
from flask_session import Session
# Create instance for Bootstrap 5
bootstrap = Bootstrap5()
# Create session instance
user_session = Session()
def create_app():
app = Flask(__name__)
# Set database location
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///notes.db'
# configure user session
app.config['SESSION_TYPE'] = 'sqlalchemy'
app.config['SESSION_PERMANENT'] = False
user_session.init_app(app)
from databases import db, User
db.init_app(app)
with app.app_context():
db.create_all()
# Database migration
'''
Required actions:
1. execute command in terminal for very first time => Flask --debug run
2. execute command in terminal => flask db init
3. execute command in terminal => flask db migrate -m "Initial migration"
4. execute command in terminal => flask db upgrade
'''
migrate = Migrate(app, db)
# Flask-WTF
app.secret_key = secrets.token_hex(8)
# initiate Bootstrap5 for the app
bootstrap.init_app(app)
from forms import new_user, login_user
@app.route('/register', methods=['GET', 'POST'])
def register():
register_user = new_user()
if register_user.validate_on_submit():
profile = User(
first_name = request.form.get('first_name'),
last_name = request.form.get('last_name'),
email = request.form.get('email'),
password = request.form.get('password')
)
db.session.add(profile)
db.session.commit()
return redirect(url_for('login'))
return render_template('new_user.html', form=register_user)
@app.route('/')
@app.route('/login', methods=['GET', 'POST'])
def login():
user_login = login_user()
if user_login.validate_on_submit():
invalid_email = None
invalid_password = None
email_input = request.form.get('email')
password_input = request.form.get('password')
checkbox = request.form.get('checkbox')
user_record = db.session().execute(
db.select(User).filter_by(email=email_input)
).scalar_one_or_none()
if not user_record:
invalid_email = f"Invalid email !!"
return render_template('login.html', form=user_login, invalid_email=invalid_email)
elif user_record.password != password_input:
invalid_password = f"Wrong password !!"
return render_template('login.html', form=user_login, invalid_password=invalid_password)
else:
user_session['email'] = email_input if checkbox else None
return redirect(url_for('profile', id=user_record.id))
return render_template('login.html', form=user_login)
@app.route('/profile/<int:id>')
def profile(id):
if user_session.get('email'):
user_record = db.session().execute(
db.select(User).filter_by(id=id)
).scalar_one_or_none()
flash(message=f"Welcome back, { user_record.first_name }", category='info')
return render_template('user_homepage.html', user=user_record)
return redirect(url_for('login'))
return app
</code>
from flask import Flask, render_template, request, redirect, url_for, flash, get_flashed_messages, session
from email_validator import validate_email, EmailNotValidError
import secrets
from flask_bootstrap import Bootstrap5
from flask_migrate import Migrate
from flask_session import Session
# Create instance for Bootstrap 5
bootstrap = Bootstrap5()
# Create session instance
user_session = Session()
def create_app():
app = Flask(__name__)
# Set database location
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///notes.db'
# configure user session
app.config['SESSION_TYPE'] = 'sqlalchemy'
app.config['SESSION_PERMANENT'] = False
user_session.init_app(app)
from databases import db, User
db.init_app(app)
with app.app_context():
db.create_all()
# Database migration
'''
Required actions:
1. execute command in terminal for very first time => Flask --debug run
2. execute command in terminal => flask db init
3. execute command in terminal => flask db migrate -m "Initial migration"
4. execute command in terminal => flask db upgrade
'''
migrate = Migrate(app, db)
# Flask-WTF
app.secret_key = secrets.token_hex(8)
# initiate Bootstrap5 for the app
bootstrap.init_app(app)
from forms import new_user, login_user
@app.route('/register', methods=['GET', 'POST'])
def register():
register_user = new_user()
if register_user.validate_on_submit():
profile = User(
first_name = request.form.get('first_name'),
last_name = request.form.get('last_name'),
email = request.form.get('email'),
password = request.form.get('password')
)
db.session.add(profile)
db.session.commit()
return redirect(url_for('login'))
return render_template('new_user.html', form=register_user)
@app.route('/')
@app.route('/login', methods=['GET', 'POST'])
def login():
user_login = login_user()
if user_login.validate_on_submit():
invalid_email = None
invalid_password = None
email_input = request.form.get('email')
password_input = request.form.get('password')
checkbox = request.form.get('checkbox')
user_record = db.session().execute(
db.select(User).filter_by(email=email_input)
).scalar_one_or_none()
if not user_record:
invalid_email = f"Invalid email !!"
return render_template('login.html', form=user_login, invalid_email=invalid_email)
elif user_record.password != password_input:
invalid_password = f"Wrong password !!"
return render_template('login.html', form=user_login, invalid_password=invalid_password)
else:
user_session['email'] = email_input if checkbox else None
return redirect(url_for('profile', id=user_record.id))
return render_template('login.html', form=user_login)
@app.route('/profile/<int:id>')
def profile(id):
if user_session.get('email'):
user_record = db.session().execute(
db.select(User).filter_by(id=id)
).scalar_one_or_none()
flash(message=f"Welcome back, { user_record.first_name }", category='info')
return render_template('user_homepage.html', user=user_record)
return redirect(url_for('login'))
return app
Appreciete if anyone can point out my mistake.