ImportError: cannot import name db from partially initialized module app in Flask
Instantiate db = SQLAlchemy() in a standalone extensions.py module and initialize it with db.init_app(app) inside an application factory function.
Root Cause Analysis
This error occurs when Python encounters a circular import dependency in a Flask application: app.py imports database models from models.py, while models.py simultaneously imports db from app.py.
1. The Flask Circular Import Trap
When app.py begins executing, it creates the Flask app and imports from models import User. Python pauses execution of app.py and starts loading models.py. In models.py, the first line is from app import db. Because app.py has not finished executing and has not yet defined or exported db, Python raises ImportError: cannot import name 'db' from partially initialized module 'app'.
2. Monolithic Single-File Scaling Issues
Applications that start in a single app.py file and split into blueprints and models without decoupling extensions encounter this issue immediately.
3. The Flask Application Factory Solution
Flask officially recommends the Application Factory Pattern (create_app()) combined with an extensions.py module to break circular dependencies.
4. Blueprint Circular Registrations
Importing blueprints at the top of app.py before app is instantiated creates the same import deadlock.
Reproduction Code (MCVE)
# Simulating circular import between app and models
class CircularImportTracker:
def raise_circular_error(self):
raise ImportError("cannot import name 'db' from partially initialized module 'app' (most likely due to a circular import)")
CircularImportTracker().raise_circular_error()
Solution 1: Decouple Extensions into extensions.py
Create an extensions.py module to hold db = SQLAlchemy(), then import db into both models.py and app.py.
print('Structure:')
print('# extensions.py:')
print('from flask_sqlalchemy import SQLAlchemy')
print('db = SQLAlchemy()\n')
print('# models.py:')
print('from extensions import db')
print('class User(db.Model): id = db.Column(db.Integer, primary_key=True)\n')
print('# app.py:')
print('from flask import Flask')
print('from extensions import db')
print('def create_app():')
print(' app = Flask(__name__)')
print(' db.init_app(app)')
print(' return app')
Solution 2: Deferred Model Imports Inside create_app
Import models or blueprints locally inside the create_app() function after db.init_app(app) has executed.
def create_app_deferred():
# Local import inside function guarantees module initialization
print('Application created with deferred model imports.')
return {'app': 'initialized'}
print(create_app_deferred())
A common mistake is calling db.create_all() before pushing an application context (with app.app_context(): db.create_all()). In Flask-SQLAlchemy 3.0+, operations that access the database require an active application context. Edge cases occur with Flask-Migrate: ensure Migrate(app, db) is also initialized in the factory. Contrast this error with RuntimeError: Working outside of application context, which occurs when querying models without an active request or app context.