Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Integrating SQLAlchemy with Flask Without Flask-SQLAlchemy

Tech May 9 3

Flask is a lightweight Python web framework that offers high flexibility and minimal built-in structure. Unlike Django, it does not include an ORM by default, so developers often integrate SQLAlchemy—a powerful SQL toolkit and ORM—for database interactions.

This guide demonstrates two approaches to using plain SQLAlchemy in Flask: declarative (class-based) mapping and classical (manual table-mapper) mapping.

Installation

Install SQLAlchemy via pip:

pip install sqlalchemy

Verify the installation:

import sqlalchemy
print(sqlalchemy.__version__)

Declarative Mapping Approach

Project Structure

.
├── app.py
├── database.py
├── models.py
├── static/
└── templates/

Database Setup (database.py)

from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base

engine = create_engine('sqlite:///./test.db', convert_unicode=True)
db_session = scoped_session(
    sessionmaker(autocommit=False, autoflush=False, bind=engine)
)
Base = declarative_base()
Base.query = db_session.query_property()

def init_db():
    import models  # Ensure models are imported before creating tables
    Base.metadata.create_all(bind=engine)

Model Definition (models.py)

from sqlalchemy import Column, Integer, String
from database import Base

class Account(Base):
    __tablename__ = 'accounts'

    id = Column(Integer, primary_key=True)
    username = Column(String(50), unique=True)
    contact = Column(String(120), unique=True)

    def __init__(self, username=None, contact=None):
        self.username = username
        self.contact = contact

    def __repr__(self):
        return f'<Account {self.username}>'

Application Entry (app.py)

from flask import Flask
from database import init_db, db_session
from models import Account

app = Flask(__name__)

@app.teardown_appcontext
def close_db(error):
    db_session.remove()

@app.route('/')
def index():
    return 'Flask + SQLAlchemy'

@app.route('/create/<username>/<contact>')
def create_user(username, contact):
    new_account = Account(username=username, contact=contact)
    try:
        db_session.add(new_account)
        db_session.commit()
        return f'Created account for {username}'
    except Exception:
        db_session.rollback()
        return 'Creation failed'

@app.route('/find/<username>')
def find_user(username):
    account = Account.query.filter_by(username=username).first()
    if account:
        return f'Found: {account.username}'
    return 'Not found'

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

The @app.teardown_appcontext ensures sessions are cleaned up after each request.

Classical Mapping Approach

In this method, table definitions and class mappings are handled explicitly.

Updated database.py

from sqlalchemy import create_engine, MetaData
from sqlalchemy.orm import scoped_session, sessionmaker

engine = create_engine('sqlite:///./test.db', convert_unicode=True)
metadata = MetaData()
db_session = scoped_session(
    sessionmaker(autocommit=False, autoflush=False, bind=engine)
)

def init_db():
    metadata.create_all(bind=engine)

Updated models.py

from sqlalchemy import Table, Column, Integer, String
from sqlalchemy.orm import mapper
from database import metadata, db_session

class Account:
    query = db_session.query_property()

    def __init__(self, username=None, contact=None):
        self.username = username
        self.contact = contact

    def __repr__(self):
        return f'<Account {self.username}>'

accounts_table = Table(
    'accounts', metadata,
    Column('id', Integer, primary_key=True),
    Column('username', String(50), unique=True),
    Column('contact', String(120), unique=True)
)

mapper(Account, accounts_table)

Application Logic (app.py)

The app.py remains largely unchanged—only the model name and routes may differ slightly. The ORM usage (.add(), .query, etc.) works identically.

Both approaches allow full control over SQLAlchemy without relying on the Flask-SQLAlchemy extension.

Tags: Flask

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Comprehensive Guide to Hive SQL Syntax and Operations

This article provides a detailed walkthrough of Hive SQL, categorizing its features and syntax for practical use. Hive SQL is segmented into the following categories: DDL Statements: Operations on...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.