0
# Model Definition
1
2
SQLModel's core functionality for defining database models that work seamlessly with both SQLAlchemy and Pydantic. This enables you to define a single class that serves as both a database table model and a data validation/serialization model.
3
4
## Capabilities
5
6
### SQLModel Base Class
7
8
The main base class for creating database models with dual SQLAlchemy and Pydantic functionality.
9
10
```python { .api }
11
class SQLModel(BaseModel, metaclass=SQLModelMetaclass):
12
"""
13
Base class for SQLModel models that combines SQLAlchemy and Pydantic functionality.
14
15
Attributes:
16
metadata: SQLAlchemy MetaData object for schema management
17
__tablename__: Table name (can be string or callable)
18
__sqlmodel_relationships__: Dictionary of relationship definitions
19
"""
20
metadata: ClassVar[MetaData]
21
__tablename__: ClassVar[Union[str, Callable[..., str]]]
22
__sqlmodel_relationships__: ClassVar[Dict[str, RelationshipProperty[Any]]]
23
24
@classmethod
25
def model_validate(
26
cls,
27
obj: Any,
28
*,
29
strict: Union[bool, None] = None,
30
from_attributes: Union[bool, None] = None,
31
context: Union[Dict[str, Any], None] = None,
32
update: Union[Dict[str, Any], None] = None,
33
) -> "SQLModel":
34
"""Validate and create a SQLModel instance from various data sources."""
35
36
def model_dump(
37
self,
38
*,
39
mode: Union[Literal["json", "python"], str] = "python",
40
include: Union[IncEx, None] = None,
41
exclude: Union[IncEx, None] = None,
42
context: Union[Dict[str, Any], None] = None,
43
by_alias: bool = False,
44
exclude_unset: bool = False,
45
exclude_defaults: bool = False,
46
exclude_none: bool = False,
47
round_trip: bool = False,
48
warnings: Union[bool, Literal["none", "warn", "error"]] = True,
49
serialize_as_any: bool = False,
50
) -> Dict[str, Any]:
51
"""Export model data as a dictionary."""
52
53
def dict(
54
self,
55
*,
56
include: Union[IncEx, None] = None,
57
exclude: Union[IncEx, None] = None,
58
by_alias: bool = False,
59
exclude_unset: bool = False,
60
exclude_defaults: bool = False,
61
exclude_none: bool = False,
62
) -> Dict[str, Any]:
63
"""Export model data as a dictionary (Pydantic v1 compatibility)."""
64
65
@classmethod
66
def from_orm(cls, obj: Any, update: Optional[Dict[str, Any]] = None) -> "SQLModel":
67
"""Create a SQLModel instance from an ORM object (deprecated, use model_validate)."""
68
69
@classmethod
70
def parse_obj(cls, obj: Any, update: Optional[Dict[str, Any]] = None) -> "SQLModel":
71
"""Parse object into SQLModel (deprecated, use model_validate)."""
72
73
def sqlmodel_update(
74
self,
75
obj: Union[Dict[str, Any], BaseModel],
76
*,
77
update: Union[Dict[str, Any], None] = None,
78
) -> "SQLModel":
79
"""Update SQLModel instance with data from another object."""
80
```
81
82
**Usage Example:**
83
```python
84
class Hero(SQLModel, table=True):
85
id: Optional[int] = Field(default=None, primary_key=True)
86
name: str
87
secret_name: str
88
age: Optional[int] = None
89
90
# The class can be used as both a Pydantic model and SQLAlchemy table
91
hero = Hero(name="Spider-Boy", secret_name="Pedro Parqueador") # Pydantic validation
92
hero_dict = hero.model_dump() # Pydantic serialization
93
# Also works as SQLAlchemy table for database operations
94
```
95
96
### Field Definition
97
98
Enhanced field definition that supports both Pydantic validation parameters and SQLAlchemy column parameters.
99
100
```python { .api }
101
# Basic field definition (most common usage)
102
def Field(
103
default: Any = Undefined,
104
*,
105
default_factory: Optional[NoArgAnyCallable] = None,
106
alias: Optional[str] = None,
107
title: Optional[str] = None,
108
description: Optional[str] = None,
109
exclude: Union[AbstractSet[Union[int, str]], Mapping[Union[int, str], Any], Any] = None,
110
include: Union[AbstractSet[Union[int, str]], Mapping[Union[int, str], Any], Any] = None,
111
const: Optional[bool] = None,
112
gt: Optional[float] = None,
113
ge: Optional[float] = None,
114
lt: Optional[float] = None,
115
le: Optional[float] = None,
116
multiple_of: Optional[float] = None,
117
max_digits: Optional[int] = None,
118
decimal_places: Optional[int] = None,
119
min_items: Optional[int] = None,
120
max_items: Optional[int] = None,
121
unique_items: Optional[bool] = None,
122
min_length: Optional[int] = None,
123
max_length: Optional[int] = None,
124
allow_mutation: bool = True,
125
regex: Optional[str] = None,
126
discriminator: Optional[str] = None,
127
repr: bool = True,
128
primary_key: Union[bool, UndefinedType] = Undefined,
129
foreign_key: Any = Undefined,
130
unique: Union[bool, UndefinedType] = Undefined,
131
nullable: Union[bool, UndefinedType] = Undefined,
132
index: Union[bool, UndefinedType] = Undefined,
133
sa_type: Union[Type[Any], UndefinedType] = Undefined,
134
sa_column_args: Union[Sequence[Any], UndefinedType] = Undefined,
135
sa_column_kwargs: Union[Mapping[str, Any], UndefinedType] = Undefined,
136
schema_extra: Optional[Dict[str, Any]] = None,
137
) -> Any: ...
138
139
# Foreign key field definition (with ondelete support)
140
def Field(
141
default: Any = Undefined,
142
*,
143
default_factory: Optional[NoArgAnyCallable] = None,
144
alias: Optional[str] = None,
145
title: Optional[str] = None,
146
description: Optional[str] = None,
147
exclude: Union[AbstractSet[Union[int, str]], Mapping[Union[int, str], Any], Any] = None,
148
include: Union[AbstractSet[Union[int, str]], Mapping[Union[int, str], Any], Any] = None,
149
const: Optional[bool] = None,
150
gt: Optional[float] = None,
151
ge: Optional[float] = None,
152
lt: Optional[float] = None,
153
le: Optional[float] = None,
154
multiple_of: Optional[float] = None,
155
max_digits: Optional[int] = None,
156
decimal_places: Optional[int] = None,
157
min_items: Optional[int] = None,
158
max_items: Optional[int] = None,
159
unique_items: Optional[bool] = None,
160
min_length: Optional[int] = None,
161
max_length: Optional[int] = None,
162
allow_mutation: bool = True,
163
regex: Optional[str] = None,
164
discriminator: Optional[str] = None,
165
repr: bool = True,
166
primary_key: Union[bool, UndefinedType] = Undefined,
167
foreign_key: str,
168
ondelete: Union[OnDeleteType, UndefinedType] = Undefined,
169
unique: Union[bool, UndefinedType] = Undefined,
170
nullable: Union[bool, UndefinedType] = Undefined,
171
index: Union[bool, UndefinedType] = Undefined,
172
sa_type: Union[Type[Any], UndefinedType] = Undefined,
173
sa_column_args: Union[Sequence[Any], UndefinedType] = Undefined,
174
sa_column_kwargs: Union[Mapping[str, Any], UndefinedType] = Undefined,
175
schema_extra: Optional[Dict[str, Any]] = None,
176
) -> Any:
177
"""
178
Define a field with both Pydantic validation and SQLAlchemy column properties.
179
180
Parameters:
181
default: Default value for the field
182
default_factory: Function to generate default values
183
alias: Alternative name for serialization
184
title: Human-readable field title
185
description: Field description
186
187
# Pydantic validation parameters
188
gt, ge, lt, le: Numeric comparison validators
189
min_length, max_length: String/sequence length validators
190
regex: Regular expression validator
191
192
# SQLAlchemy column parameters
193
primary_key: Whether this field is a primary key
194
foreign_key: Foreign key reference (table.column format)
195
ondelete: Foreign key on-delete behavior
196
unique: Whether values must be unique
197
nullable: Whether NULL values are allowed
198
index: Whether to create an index
199
sa_type: Explicit SQLAlchemy type
200
sa_column: Pre-configured SQLAlchemy Column object
201
sa_column_args: Additional positional args for Column
202
sa_column_kwargs: Additional keyword args for Column
203
204
Returns:
205
FieldInfo object with combined Pydantic and SQLAlchemy configuration
206
"""
207
```
208
209
**Usage Examples:**
210
```python
211
class User(SQLModel, table=True):
212
# Primary key field
213
id: Optional[int] = Field(default=None, primary_key=True)
214
215
# Required string with validation
216
username: str = Field(min_length=3, max_length=50, unique=True)
217
218
# Optional field with database index
219
email: Optional[str] = Field(default=None, index=True)
220
221
# Foreign key field
222
team_id: Optional[int] = Field(default=None, foreign_key="team.id", ondelete="SET NULL")
223
224
# Field with custom SQLAlchemy type
225
status: str = Field(sa_type=VARCHAR(20), default="active")
226
```
227
228
### Relationship Definition
229
230
Define relationships between SQLModel models with support for various relationship patterns.
231
232
```python { .api }
233
def Relationship(
234
*,
235
back_populates: Optional[str] = None,
236
cascade_delete: Optional[bool] = False,
237
passive_deletes: Optional[Union[bool, Literal["all"]]] = False,
238
link_model: Optional[Any] = None,
239
sa_relationship: Optional[RelationshipProperty[Any]] = None,
240
sa_relationship_args: Optional[Sequence[Any]] = None,
241
sa_relationship_kwargs: Optional[Mapping[str, Any]] = None,
242
) -> Any:
243
"""
244
Define relationships between SQLModel models.
245
246
Parameters:
247
back_populates: Name of the reverse relationship attribute
248
cascade_delete: Whether to cascade delete operations
249
passive_deletes: How to handle deletes (True, False, or "all")
250
link_model: Model class for many-to-many relationships
251
sa_relationship: Pre-configured SQLAlchemy relationship
252
sa_relationship_args: Additional positional args for relationship
253
sa_relationship_kwargs: Additional keyword args for relationship
254
255
Returns:
256
RelationshipInfo object with relationship configuration
257
"""
258
```
259
260
**Usage Examples:**
261
```python
262
class Team(SQLModel, table=True):
263
id: Optional[int] = Field(default=None, primary_key=True)
264
name: str
265
266
# One-to-many relationship
267
heroes: List["Hero"] = Relationship(back_populates="team")
268
269
class Hero(SQLModel, table=True):
270
id: Optional[int] = Field(default=None, primary_key=True)
271
name: str
272
team_id: Optional[int] = Field(default=None, foreign_key="team.id")
273
274
# Many-to-one relationship
275
team: Optional[Team] = Relationship(back_populates="heroes")
276
277
# Many-to-many with link model
278
class HeroTeamLink(SQLModel, table=True):
279
team_id: Optional[int] = Field(default=None, foreign_key="team.id", primary_key=True)
280
hero_id: Optional[int] = Field(default=None, foreign_key="hero.id", primary_key=True)
281
282
class Hero(SQLModel, table=True):
283
id: Optional[int] = Field(default=None, primary_key=True)
284
name: str
285
286
teams: List[Team] = Relationship(back_populates="heroes", link_model=HeroTeamLink)
287
```
288
289
### Field and Relationship Info Classes
290
291
Information classes that store field and relationship configuration.
292
293
```python { .api }
294
class FieldInfo(PydanticFieldInfo):
295
"""
296
Extended FieldInfo with SQLAlchemy-specific attributes.
297
298
Attributes:
299
primary_key: Whether this is a primary key field
300
nullable: Whether NULL values are allowed
301
foreign_key: Foreign key reference
302
ondelete: Foreign key on-delete behavior
303
unique: Whether values must be unique
304
index: Whether to create an index
305
sa_type: SQLAlchemy type override
306
sa_column: Pre-configured Column object
307
sa_column_args: Additional Column positional arguments
308
sa_column_kwargs: Additional Column keyword arguments
309
"""
310
primary_key: bool
311
nullable: Union[bool, UndefinedType]
312
foreign_key: Any
313
ondelete: Union[OnDeleteType, UndefinedType]
314
unique: Union[bool, UndefinedType]
315
index: Union[bool, UndefinedType]
316
sa_type: Union[Type[Any], UndefinedType]
317
sa_column: Union[Column, UndefinedType]
318
sa_column_args: Union[Sequence[Any], UndefinedType]
319
sa_column_kwargs: Union[Mapping[str, Any], UndefinedType]
320
321
class RelationshipInfo:
322
"""
323
Information class for relationship configuration.
324
325
Attributes:
326
back_populates: Name of the reverse relationship
327
cascade_delete: Whether to cascade deletes
328
passive_deletes: Passive delete handling
329
link_model: Model for many-to-many relationships
330
sa_relationship: Pre-configured relationship
331
sa_relationship_args: Additional relationship args
332
sa_relationship_kwargs: Additional relationship kwargs
333
"""
334
back_populates: Optional[str]
335
cascade_delete: bool
336
passive_deletes: Union[bool, Literal["all"]]
337
link_model: Optional[Any]
338
sa_relationship: Optional[RelationshipProperty[Any]]
339
sa_relationship_args: Optional[Sequence[Any]]
340
sa_relationship_kwargs: Optional[Mapping[str, Any]]
341
```
342
343
### Metaclass
344
345
The metaclass that combines Pydantic and SQLAlchemy functionality.
346
347
```python { .api }
348
class SQLModelMetaclass(ModelMetaclass, DeclarativeMeta):
349
"""
350
Metaclass that combines Pydantic ModelMetaclass and SQLAlchemy DeclarativeMeta.
351
352
This metaclass enables SQLModel classes to work as both Pydantic models
353
and SQLAlchemy table models simultaneously.
354
"""
355
__sqlmodel_relationships__: Dict[str, RelationshipInfo]
356
model_config: SQLModelConfig
357
model_fields: Dict[str, FieldInfo]
358
```
359
360
## Types
361
362
```python { .api }
363
UndefinedType = type(None) # Placeholder for undefined values
364
Undefined: UndefinedType # Singleton undefined value
365
366
OnDeleteType = Literal["CASCADE", "SET NULL", "RESTRICT"] # Foreign key delete actions
367
368
NoArgAnyCallable = Callable[[], Any] # Callable with no arguments returning Any
369
370
IncEx = Union[
371
Set[int],
372
Set[str],
373
Mapping[int, Union["IncEx", bool]],
374
Mapping[str, Union["IncEx", bool]],
375
] # Include/exclude type for model serialization
376
```