DEV Community

Matt Tran
Matt Tran

Posted on

Using Flask-SQLAlchemy Validations

Flask, the lightweight web framework for Python, empowers developers to create dynamic and feature-rich web applications. When it comes to managing data and ensuring its integrity, Flask-SQLAlchemy plays a pivotal role. In this tutorial, we'll explore how to implement validations using Flask-SQLAlchemy, safeguarding your web application against incorrect or malicious data.

Prerequisites

Before diving into validations, make sure you have Flask and Flask-SQLAlchemy installed. You can install them using:

bash

pip install Flask Flask-SQLAlchemy
Enter fullscreen mode Exit fullscreen mode

Additionally, set up a basic Flask application and configure Flask-SQLAlchemy to connect to your database.

Defining Models

In Flask-SQLAlchemy, models are Python classes that represent database tables. Start by defining your models, specifying the fields and data types. For example:

python

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
Enter fullscreen mode Exit fullscreen mode

Here, we've created a User model with id, username, and email columns.

Adding Validations

To enforce data integrity, add validations to your model fields. Flask-SQLAlchemy supports a range of validation options. Let's explore a few:

  1. Required Fields Ensure that certain fields are not empty. For example, to make the email field required, modify the User class:

python

from sqlalchemy.orm import validates

class User(db.Model):
    # ... (previous fields)

    @validates('email')
    def validate_email(self, key, email):
        if not email:
            raise ValueError("Email cannot be empty.")
        return email

Enter fullscreen mode Exit fullscreen mode
  1. Unique Constraints Prevent duplicate entries in specific columns. To enforce uniqueness on the username field:

python

class User(db.Model):
    # ... (previous fields)

    @validates('username')
    def validate_username(self, key, username):
        existing_user = User.query.filter(User.username == username).first()
        if existing_user:
            raise ValueError("Username must be unique.")
        return username

Enter fullscreen mode Exit fullscreen mode
  1. Custom Validations Implement custom validations based on your application's requirements. For instance, validating the length of the username:

python

class User(db.Model):
    # ... (previous fields)

    @validates('username')
    def validate_username_length(self, key, username):
        if len(username) < 4 or len(username) > 20:
            raise ValueError("Username must be between 4 and 20 characters.")
        return username
Enter fullscreen mode Exit fullscreen mode

Applying Migrations

After you add the validations, apply the changes to the database using Flask-Migrate:

bash

flask db init
flask db migrate -m "Adding validations to User model"
flask db upgrade
Enter fullscreen mode Exit fullscreen mode

Doing this you'll be able to initialize the migration, create the script, and make those changes to the database.

Lets Test Validations

Now it's time to create tests and make sure our validations work! Use testing libraries like unittest or pytest to write test cases that cover various scenarios.

python

import unittest
from your_flask_app import app, db, User

class TestUserModel(unittest.TestCase):
    def setUp(self):
        app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:'
        app.config['TESTING'] = True
        db.init_app(app)
        with app.app_context():
            db.create_all()

    def tearDown(self):
        with app.app_context():
            db.session.remove()
            db.drop_all()

    def test_email_validation(self):
        with app.app_context():
            with self.assertRaises(ValueError):
                user = User(username='test_user', email='')
                db.session.add(user)
                db.session.commit()

    # Add more test cases for other validations...

if __name__ == '__main__':
    unittest.main()
Enter fullscreen mode Exit fullscreen mode

Make sure your tests covers different validations cases and behaves the way you want it to.

Conclusion

Overall, validations will help ensure data integrity. Therefore, adding validations to your Flask-SQLAlchemy models is crucial if you want to create a foundation that can handle and store data securely! 

Top comments (0)