When integrating SQLAlchemy with Flask using the Flask-SQLAlchemy extension, a common error encountered during application setup is RuntimeError: Either 'SQLALCHEMY_DATABASE_URI' or 'SQLALCHEMY_BINDS' must be set. This error signifies that Flask-SQLAlchemy cannot determine which database(s) to connect to because the necessary configuration variables are missing or not set correctly before the extension tries to initialize itself with your Flask application.
This guide explains why this configuration is essential and provides clear steps to correctly set up your database connection URI.
Understanding the Error: SQLAlchemy Configuration
Flask-SQLAlchemy acts as a bridge between your Flask application and the SQLAlchemy ORM (Object Relational Mapper). To function, it needs to know how to connect to your database(s). This connection information is primarily provided through Flask's application configuration system.
The extension looks for one of these configuration keys:
SQLALCHEMY_DATABASE_URI: A single string specifying the connection details for the default database.SQLALCHEMY_BINDS: A dictionary allowing you to configure connections to multiple databases, each identified by a "bind key".
If neither of these keys is found in the app.config dictionary when Flask-SQLAlchemy initializes its connection to your Flask app instance, it raises the RuntimeError because it has no database target.
Common Causes
- Missing Configuration: You simply forgot to add
app.config['SQLALCHEMY_DATABASE_URI'] = '...'orapp.config['SQLALCHEMY_BINDS'] = {...}to your code. - Configuration Set Too Late: You set the configuration variable after initializing the Flask-SQLAlchemy extension with your app instance (e.g., after calling
db.init_app(app)ordb = SQLAlchemy(app)). SQLAlchemy needs the config before or during this initialization step. - Misspelled Configuration Key: Typing
SQLALCHEMY_DATABASE_URLinstead ofSQLALCHEMY_DATABASE_URI, or other typos. - Incorrect URI Format: Providing an invalid database connection string (e.g., using
sqlite://instead ofsqlite:///for a relative SQLite path).
Solution 1: Set SQLALCHEMY_DATABASE_URI Before Initialization (Recommended)
This is the most common scenario and solution. Ensure the SQLALCHEMY_DATABASE_URI key is set in app.config before Flask-SQLAlchemy attempts to use it during initialization. There are two main patterns for initializing Flask-SQLAlchemy:
Method A: db = SQLAlchemy() then db.init_app(app) (Factory Pattern)
This pattern is common when using application factories.
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydatabase.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db.init_app(app)
class Item(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), unique=True, nullable=False)
@app.route('/')
def index():
with app.app_context():
items = Item.query.all()
return f"Items: {[item.name for item in items]}"
if __name__ == '__main__':
app.run(debug=True)Crucially, app.config[...] = ... happens before db.init_app(app).
Method B: db = SQLAlchemy(app) (Simpler Setup)
This pattern directly binds the SQLAlchemy instance to the app upon creation.
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydatabase.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
class Item(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), unique=True, nullable=False)
@app.route('/')
def index():
with app.app_context():
items = Item.query.all()
return f"Items: {[item.name for item in items]}"
if __name__ == '__main__':
app.run(debug=True)Again, the key is that app.config[...] = ... is executed before SQLAlchemy(app).
Solution 2: Verify Configuration Key Name (SQLALCHEMY_DATABASE_URI)
Double-check for typos. The correct key name is SQLALCHEMY_DATABASE_URI. A common mistake is typing SQLALCHEMY_DATABASE_URL.
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydatabase.db'Solution 3: Use Correct Database URI Format
The format of the connection string depends on the database type.
SQLite Relative Path (sqlite:///)
To create a SQLite database file relative to your application's instance folder, use three forward slashes.
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydatabase.db'Using only two slashes (sqlite://mydatabase.db) is often misinterpreted and can lead to errors or unexpected database locations.
SQLite Absolute Path (sqlite://// or sqlite:///C:/...)
- Linux/macOS: To specify an absolute path, use four forward slashes after
sqlite:, followed by the full path.app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////path/to/your/database/app_data.db' - Windows: Use three forward slashes followed by the absolute path (which usually starts with a drive letter like
C:).app.config['SQLALCHEMY_DATABASE_URI'] = r'sqlite:///C:/path/to/your/database/app_data.db'
Other Databases (PostgreSQL, MySQL)
Formats vary but generally follow dialect+driver://username:password@host:port/database. Consult SQLAlchemy documentation for specific dialects.
Note on SQLALCHEMY_BINDS
If you need to connect to multiple databases, you use SQLALCHEMY_BINDS instead of SQLALCHEMY_DATABASE_URI. It takes a dictionary where keys are "bind keys" used in your models, and values are the database URIs.
app.config['SQLALCHEMY_BINDS'] = {
'users': 'postgresql://user:pass@host/users_db',
'inventory': 'sqlite:///inventory.db'
}The RuntimeError mentions this as an alternative required key.
Debugging the Configuration
If you're still getting the error, check what Flask actually sees in its configuration right before SQLAlchemy initialization:
print("DEBUG: SQLALCHEMY_DATABASE_URI =", app.config.get('SQLALCHEMY_DATABASE_URI'))
print("DEBUG: SQLALCHEMY_BINDS =", app.config.get('SQLALCHEMY_BINDS'))
db.init_app(app) # Or db = SQLAlchemy(app)This will show you if the variable is None (meaning it wasn't set correctly or was misspelled) or if it has an unexpected value.
Conclusion
The RuntimeError: Either 'SQLALCHEMY_DATABASE_URI' or 'SQLALCHEMY_BINDS' must be set in Flask-SQLAlchemy is a configuration error. It means the extension was initialized with the Flask app before the necessary database connection string was set in app.config.
To fix it:
- Ensure you set
app.config['SQLALCHEMY_DATABASE_URI'](orapp.config['SQLALCHEMY_BINDS']) with a valid connection string. - Make sure this configuration happens before you call
db.init_app(app)ordb = SQLAlchemy(app). - Double-check the spelling of the configuration key (
SQLALCHEMY_DATABASE_URI). - Verify the database URI format is correct for your database type (especially the number of slashes for SQLite).
By correctly setting the database URI in the Flask app configuration prior to initializing Flask-SQLAlchemy, you will resolve this common runtime error.