Skip to the content.

Day 2: Database Setup, Models, and User Authentication


Theory (10 AM - 12:30 PM)


1. Flask-SQLAlchemy: Introduction and Setup

Objective: Learn how to set up and use Flask-SQLAlchemy for handling SQLite database operations in a Flask web application.


What is SQLAlchemy?


Steps to Set Up Flask-SQLAlchemy:

  1. Install Flask-SQLAlchemy via pip:

    pip install flask-sqlalchemy
    
  2. Flask App Configuration: Flask-SQLAlchemy needs to be configured to connect your Flask application with a database. In this example, we use SQLite, a lightweight relational database.

    Here's the basic configuration I used in the Python code:

    from flask import Flask
    from flask_sqlalchemy import SQLAlchemy
    
    app = Flask(__name__)
    
    # Flask-SQLAlchemy Configuration
    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'  # SQLite database file
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False  # Disable modification tracking (to reduce overhead)
    app.config['SECRET_KEY'] = 'mysecretkey'  # Secret key for session management
    app.config['SECURITY_PASSWORD_SALT'] = 'mysecretsalt'  # Salt for password hashing
    
    db = SQLAlchemy(app)
    

Explanation of the Configuration:


2. Database Models: Defining Entities

Objective: Learn how to define models (representations of tables) in your SQLite database using SQLAlchemy.

Creating Models in SQLAlchemy: Models are Python classes that represent database tables. Each class corresponds to a table, and each attribute corresponds to a column in the table.


Example: Defining a User Model

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)  # unique identifier for each user
    username = db.Column(db.String(120), unique=True, nullable=False)  # user's username
    email = db.Column(db.String(120), unique=True, nullable=False)  # user's email
    password = db.Column(db.String(60), nullable=False)  # hashed password
    roles = db.relationship('Role', secondary='user_roles')  # many-to-many relationship with Role

Explanation of Attributes:


3. User Authentication: Setting Up with Flask-Security

Objective: Learn how to handle user authentication securely using Flask-Security, which integrates user authentication, role management, password hashing, and more.


UserMixin and RoleMixin:

  1. UserMixin:

    • The UserMixin class gives the User model a set of methods that Flask-Security needs for user management. These include methods like get_id(), is_authenticated(), is_active(), is_anonymous(), and set_password(). These methods are used by Flask-Login (used internally by Flask-Security) to manage user sessions.
    class User(db.Model, UserMixin):
        id = db.Column(db.Integer, primary_key=True)
        username = db.Column(db.String(120), unique=True, nullable=False)
        email = db.Column(db.String(120), unique=True, nullable=False)
        password = db.Column(db.String(60), nullable=False)
        roles = db.relationship('Role', secondary='user_roles')
    
  2. RoleMixin:

    • The RoleMixin class gives the Role model a set of methods for role management, including the ability to check whether a user has a certain role or permission.
    class Role(db.Model, RoleMixin):
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(80), unique=True)
    

4. Relationship: One-to-Many and Many-to-Many

One-to-Many Relationship:

Example:

class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(100), nullable=False)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))  # Foreign key to User

    user = db.relationship('User', back_populates='posts')

Many-to-Many Relationship:

Example (Many-to-Many):

class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(120), unique=True, nullable=False)
    roles = db.relationship('Role', secondary='user_roles')  # Many-to-many relationship

class Role(db.Model, RoleMixin):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), unique=True)

user_roles = db.Table('user_roles',  # Association table
                      db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
                      db.Column('role_id', db.Integer(), db.ForeignKey('role.id')))

5. Using Flask-Security for User Authentication

Objective: Learn how to handle user authentication securely using Flask-Security, which integrates user authentication, role management, password hashing, and more.

Here’s the setup:

  1. Install Flask-Security:

    pip install flask-security
    
  2. Set Up User Registration and Authentication:

from flask_security import Security, SQLAlchemyUser

Datastore, UserMixin, RoleMixin
from flask import Flask, render_template, request, redirect, url_for

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
app.config['SECRET_KEY'] = 'mysecretkey'
app.config['SECURITY_PASSWORD_SALT'] = 'mysecretsalt'

db = SQLAlchemy(app)

# Define User and Role models
class Role(db.Model, RoleMixin):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), unique=True)

class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(120), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
    password = db.Column(db.String(60), nullable=False)
    roles = db.relationship('Role', secondary='user_roles')

user_roles = db.Table('user_roles',
                      db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
                      db.Column('role_id', db.Integer(), db.ForeignKey('role.id')))

# Initialize user datastore
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security = Security(app, user_datastore)

if __name__ == '__main__':
    app.run(debug=True)

Key Concepts to Remember:


This document provide a solid understanding of database models, relationships, and the configurations used in Flask-SQLAlchemy!