Of course! sqlacodegen is an incredibly useful command-line tool that automatically generates Python model code for SQLAlchemy from an existing database. It saves you a massive amount of time when you need to reverse-engineer a database schema.

Here’s a complete guide covering what it is, why you'd use it, how to install and run it, and how to interpret the output.
What is sqlacodegen?
sqlacodegen is a tool that introspects a database (by connecting to it) and reads its schema (tables, columns, data types, relationships, indexes, etc.). It then generates Python code that defines these tables as SQLAlchemy ORM (Object-Relational Mapping) models.
In short, it turns a database schema into a Python file you can use in your application.
Why Use It?
- Rapid Prototyping: Get a basic ORM model for an existing database in seconds, allowing you to start building your application immediately.
- Legacy Database Integration: When you're handed a database with no existing Python code,
sqlacodegenprovides a solid starting point for your models. - Documentation: The generated code serves as a clear, machine-readable representation of your database structure.
- Learning: It's a great way to see how complex database schemas (like those with foreign keys and many-to-many relationships) are represented in SQLAlchemy.
Step 1: Installation
First, you need to install sqlacodegen. It's available on PyPI.

pip install sqlacodegen
You will also need a database driver for the specific database you're connecting to. For example:
- PostgreSQL:
pip install psycopg2-binary - MySQL:
pip install PyMySQLorpip install mysql-connector-python - SQLite:
pip install pysqlite3(or use the built-insqlite3) - SQL Server:
pip install pymssql
Step 2: Basic Usage
The command structure is simple:
sqlacodegen <database_uri> > models.py
Let's break this down:
sqlacodegen: The command you run.<database_uri>: The connection string to your database. This is the most important part.>: A shell redirect operator. It takes the output from the command and writes it into a file.models.py: The name of the output file where the generated code will be saved.
Database URI Examples
The format of the database URI depends on the database you're using.
| Database | Example URI |
|---|---|
| SQLite | sqlite:///path/to/your/database.db (Three slashes for a relative path) |
sqlite:////absolute/path/to/your/database.db (Four slashes for an absolute path) |
|
| PostgreSQL | postgresql://user:password@host:port/database_name |
| MySQL | mysql+pymysql://user:password@host:port/database_name |
| SQL Server | mssql+pymssql://user:password@host:port/database_name |
Step 3: A Complete Example with SQLite
Let's walk through a full example.
Create a Sample SQLite Database
First, let's create a simple database with a couple of tables and some relationships.
# setup_db.py
import sqlite3
# Connect to the database (it will be created if it doesn't exist)
conn = sqlite3.connect('my_database.db')
cursor = conn.cursor()
# Create a 'users' table
cursor.execute('''
CREATE TABLE users (
id INTEGER PRIMARY KEY,
username TEXT NOT NULL UNIQUE,
email TEXT NOT NULL,
full_name TEXT
)
''')
# Create a 'posts' table
cursor.execute('''
CREATE TABLE posts (
id INTEGER PRIMARY KEY,TEXT NOT NULL,
content TEXT,
user_id INTEGER,
FOREIGN KEY (user_id) REFERENCES users (id)
)
''')
# Create a 'tags' table
cursor.execute('''
CREATE TABLE tags (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL UNIQUE
)
''')
# Create a 'post_tags' junction table for a many-to-many relationship
cursor.execute('''
CREATE TABLE post_tags (
post_id INTEGER,
tag_id INTEGER,
PRIMARY KEY (post_id, tag_id),
FOREIGN KEY (post_id) REFERENCES posts (id),
FOREIGN KEY (tag_id) REFERENCES tags (id)
)
''')
# Commit the changes and close the connection
conn.commit()
conn.close()
print("Database 'my_database.db' created successfully.")
Run this script to generate my_database.db.
Run sqlacodegen
Now, run the generator on the database you just created.
sqlacodegen sqlite:///my_database.db > models.py
Inspect the Generated models.py
The tool will create a models.py file. Here is what it will look like, with explanations for each part.
# models.py
from sqlalchemy import Column, ForeignKey, Integer, String, Table
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
metadata = Base.metadata
# This is the "junction table" for the many-to-many relationship.
# It's automatically detected and created as a Table object.
t_post_tags = Table(
'post_tags', metadata,
Column('post_id', Integer, ForeignKey('posts.id')),
Column('tag_id', Integer, ForeignKey('tags.id'))
)
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
username = Column(String, nullable=False, unique=True)
email = Column(String, nullable=False)
full_name = Column(String)
# This defines the one-to-many relationship: one User can have many Posts.
# The `back_populates` ensures the relationship is two-way.
posts = relationship("Post", back_populates="user")
class Post(Base):
__tablename__ = 'posts'
id = Column(Integer, primary_key=True)= Column(String, nullable=False)
content = Column(String)
user_id = Column(Integer, ForeignKey('users.id'))
# This is the "many" side of the one-to-many relationship.
# It links back to the User.
user = relationship("User", back_populates="posts")
# This defines the many-to-many relationship: a Post can have many Tags.
# The `secondary` argument points to our junction table.
tags = relationship("Tag", secondary=t_post_tags, back_populates="posts")
class Tag(Base):
__tablename__ = 'tags'
id = Column(Integer, primary_key=True)
name = Column(String, nullable=False, unique=True)
# This is the other side of the many-to-many relationship.
# It links back to the Post.
posts = relationship("Post", secondary=t_post_tags, back_populates="tags")
Key Takeaways from the Output:
Base = declarative_base(): This is the standard base class for your SQLAlchemy ORM models.__tablename__ = 'users': Each class corresponds to a database table.Column(...): Each attribute in the class is a column, with its type (Integer,String) and constraints (primary_key=True,nullable=False,unique=True).ForeignKey(...): This correctly identifies foreign key relationships.relationship(...): This is the magic of SQLAlchemy ORM. It defines how tables relate to each other.- One-to-Many (
User->Post): TheUserhas apostsrelationship, and thePosthas auserrelationship.back_populateslinks them together. - Many-to-Many (
Post<->Tag): The tool correctly identifies the junction table (post_tags) and uses thesecondaryargument in therelationship()to define the link. BothPostandTaghave a relationship back to each other.
- One-to-Many (
Advanced Options and Flags
sqlacodegen offers several useful flags to customize the output.
You can see all options by running sqlacodegen --help.
Here are some of the most common ones:
| Flag | Description | Example |
|---|---|---|
--tables |
Generate models for only the specified tables. | sqlacodegen --tables users,posts sqlite:///my_database.db |
--schema |
Specify a schema name (useful for PostgreSQL). | sqlacodegen --schema public postgresql://... |
--no-constraints |
Do not generate primary_key, nullable, or unique constraints. |
sqlacodegen --no-constraints sqlite:///... |
--no-engine |
Do not generate the create_engine() call. |
sqlacodegen --no-engine sqlite:///... |
--flask |
Generate Flask-SQLAlchemy models (uses db.Model instead of Base). |
sqlacodegen --flask sqlite:///... |
--novel |
Generate a more modern, "novel" style of SQLAlchemy 2.0 code. | sqlacodegen --novel sqlite:///... |
Example: Generating for Specific Tables
If your database is huge and you only need a few tables, this is a huge time-saver.
# Only generate the User and Post models sqlacodegen --tables users,posts sqlite:///my_database.db > user_post_models.py
This will produce a much smaller file containing only the User and Post classes and their relationship.
