0
# Extension Setup and Configuration
1
2
Core extension class initialization, Flask app integration, and database configuration management. This includes setting up database URIs, engine options, and binding multiple databases.
3
4
## Capabilities
5
6
### SQLAlchemy Extension Class
7
8
The main extension class that integrates SQLAlchemy with Flask applications. Handles initialization, configuration, and provides access to database resources.
9
10
```python { .api }
11
class SQLAlchemy:
12
def __init__(
13
self,
14
app: Flask | None = None,
15
*,
16
metadata: sa.MetaData | None = None,
17
session_options: dict[str, Any] | None = None,
18
query_class: type[Query] = Query,
19
model_class = Model,
20
engine_options: dict[str, Any] | None = None,
21
add_models_to_shell: bool = True,
22
disable_autonaming: bool = False,
23
):
24
"""
25
Initialize the SQLAlchemy extension.
26
27
Parameters:
28
- app: Flask application instance or None for later initialization
29
- metadata: Custom metadata instance for table definitions
30
- session_options: Options passed to sessionmaker
31
- query_class: Custom query class for Model.query
32
- model_class: Custom model base class or declarative base
33
- engine_options: Default options for all database engines
34
- add_models_to_shell: Add db and models to Flask shell context
35
- disable_autonaming: Disable automatic table name generation
36
"""
37
38
def init_app(self, app: Flask) -> None:
39
"""
40
Initialize the extension with a Flask application.
41
42
Must be called before accessing database resources. Sets up:
43
- Database configuration from app.config
44
- Engine creation for all bind keys
45
- Session teardown handlers
46
- Optional shell context processors
47
48
Parameters:
49
- app: Flask application to configure
50
"""
51
52
def __repr__(self) -> str:
53
"""String representation showing engine info and bind count."""
54
```
55
56
### Database Engine Management
57
58
Properties and methods for accessing and managing database engines across multiple databases.
59
60
```python { .api }
61
@property
62
def engine(self) -> sa.engine.Engine:
63
"""The default database engine for the current application."""
64
65
@property
66
def engines(self) -> Mapping[str | None, sa.engine.Engine]:
67
"""Map of bind keys to engine instances for current application."""
68
69
def get_engine(
70
self, bind_key: str | None = None, **kwargs: Any
71
) -> sa.engine.Engine:
72
"""
73
Get the engine for the given bind key (deprecated).
74
75
Parameters:
76
- bind_key: The name of the engine, None for default
77
78
Returns:
79
Engine instance for the specified bind key
80
81
Note: Deprecated in favor of engines[key] property
82
"""
83
```
84
85
### Database Schema Operations
86
87
Methods for creating, dropping, and reflecting database schemas across all or specific bind keys.
88
89
```python { .api }
90
def create_all(self, bind_key: str | None | list[str | None] = "__all__") -> None:
91
"""
92
Create tables that do not exist in the database.
93
94
Parameters:
95
- bind_key: Bind key(s) to create tables for, "__all__" for all binds
96
"""
97
98
def drop_all(self, bind_key: str | None | list[str | None] = "__all__") -> None:
99
"""
100
Drop all tables from the database.
101
102
Parameters:
103
- bind_key: Bind key(s) to drop tables from, "__all__" for all binds
104
"""
105
106
def reflect(self, bind_key: str | None | list[str | None] = "__all__") -> None:
107
"""
108
Load table definitions from the database.
109
110
Parameters:
111
- bind_key: Bind key(s) to reflect tables from, "__all__" for all binds
112
"""
113
```
114
115
### Metadata Management
116
117
Properties for accessing metadata instances that define table schemas.
118
119
```python { .api }
120
@property
121
def metadata(self) -> sa.MetaData:
122
"""The default metadata used by Model and Table."""
123
124
@property
125
def metadatas(self) -> dict[str | None, sa.MetaData]:
126
"""Map of bind keys to MetaData instances."""
127
```
128
129
### SQLAlchemy Integration
130
131
Direct access to SQLAlchemy classes and functions through the extension instance, plus enhanced relationship methods that automatically apply the extension's Query class.
132
133
```python { .api }
134
def relationship(self, *args: Any, **kwargs: Any) -> sa_orm.RelationshipProperty[Any]:
135
"""
136
Create a SQLAlchemy relationship that applies this extension's Query class
137
for dynamic relationships and backrefs.
138
139
This is a wrapper around sqlalchemy.orm.relationship that automatically
140
sets the query_class for dynamic relationships and backref configurations.
141
142
Parameters:
143
- args: Arguments passed to sqlalchemy.orm.relationship
144
- kwargs: Keyword arguments passed to sqlalchemy.orm.relationship
145
146
Returns:
147
RelationshipProperty configured with Flask-SQLAlchemy's Query class
148
"""
149
150
def dynamic_loader(self, argument: Any, **kwargs: Any) -> sa_orm.RelationshipProperty[Any]:
151
"""
152
Create a dynamic loader relationship that applies this extension's Query class.
153
154
This is a wrapper around sqlalchemy.orm.dynamic_loader that automatically
155
sets the query_class for relationships and backref configurations.
156
157
Parameters:
158
- argument: Mapper or class to relate to
159
- kwargs: Keyword arguments passed to sqlalchemy.orm.dynamic_loader
160
161
Returns:
162
RelationshipProperty configured for dynamic loading with Flask-SQLAlchemy's Query class
163
"""
164
165
def __getattr__(self, name: str) -> Any:
166
"""
167
Proxy access to sqlalchemy and sqlalchemy.orm modules.
168
169
Allows convenient access like db.Column, db.Integer, db.relationship, etc.
170
Special handling for 'event' -> sqlalchemy.event and deprecated 'relation'.
171
"""
172
```
173
174
## Usage Examples
175
176
### Basic Setup
177
178
```python
179
from flask import Flask
180
from flask_sqlalchemy import SQLAlchemy
181
182
app = Flask(__name__)
183
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///app.db"
184
185
db = SQLAlchemy(app)
186
# or
187
db = SQLAlchemy()
188
db.init_app(app)
189
```
190
191
### Multiple Database Configuration
192
193
```python
194
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///main.db"
195
app.config["SQLALCHEMY_BINDS"] = {
196
"users": "sqlite:///users.db",
197
"logs": "postgresql://user:pass@localhost/logs"
198
}
199
200
db = SQLAlchemy(app)
201
202
# Engines are automatically created for each bind
203
with app.app_context():
204
main_engine = db.engine # Default bind
205
users_engine = db.engines["users"]
206
logs_engine = db.engines["logs"]
207
```
208
209
### Custom Configuration
210
211
```python
212
from sqlalchemy.orm import DeclarativeBase
213
214
class Base(DeclarativeBase):
215
pass
216
217
db = SQLAlchemy(
218
app,
219
model_class=Base,
220
engine_options={"pool_timeout": 30},
221
disable_autonaming=True
222
)
223
```
224
225
### Relationship Configuration
226
227
```python
228
class User(db.Model):
229
id = db.Column(db.Integer, primary_key=True)
230
posts = db.relationship('Post', backref='author')
231
# or explicitly use db.relationship for Flask-SQLAlchemy Query class
232
posts = db.relationship('Post', backref=db.backref('author', lazy='dynamic'))
233
234
class Post(db.Model):
235
id = db.Column(db.Integer, primary_key=True)
236
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
237
238
# Dynamic loading with Flask-SQLAlchemy Query class
239
comments = db.dynamic_loader('Comment', backref='post')
240
241
# Query using the enhanced Query class
242
user = User.query.first()
243
user.posts.filter_by(published=True).all() # Uses Flask-SQLAlchemy Query methods
244
```
245
246
## Configuration Keys
247
248
- **SQLALCHEMY_DATABASE_URI**: Default database connection URI
249
- **SQLALCHEMY_ENGINE_OPTIONS**: Default engine configuration options
250
- **SQLALCHEMY_ECHO**: Enable SQLAlchemy query logging (boolean)
251
- **SQLALCHEMY_BINDS**: Mapping of bind keys to database URIs or configuration dicts
252
- **SQLALCHEMY_RECORD_QUERIES**: Enable query recording for debugging (boolean)
253
- **SQLALCHEMY_TRACK_MODIFICATIONS**: Enable model change tracking (boolean)