or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

bson-types.mdengines.mdfields.mdindex.mdindexes.mdmodels.mdqueries.mdsessions.md

fields.mddocs/

0

# Fields

1

2

ODMantic field definitions provide MongoDB-specific options for model attributes, including indexing, validation, primary keys, and custom MongoDB field names.

3

4

## Capabilities

5

6

### Field Function

7

8

Define model fields with MongoDB-specific configuration options.

9

10

```python { .api }

11

def Field(

12

default=...,

13

*,

14

key_name=None,

15

primary_field=False,

16

index=False,

17

unique=False,

18

default_factory=None,

19

title=None,

20

description=None,

21

json_schema_extra=None,

22

const=None,

23

gt=None,

24

ge=None,

25

lt=None,

26

le=None,

27

multiple_of=None,

28

min_items=None,

29

max_items=None,

30

min_length=None,

31

max_length=None,

32

regex=None,

33

examples=None

34

):

35

"""

36

Define a model field with MongoDB-specific options.

37

38

Args:

39

default: Default value for the field (use ... for required fields)

40

key_name: MongoDB field name (different from Python attribute name)

41

primary_field: Mark this field as primary key (_id in MongoDB)

42

index: Create an index on this field

43

unique: Create a unique index on this field

44

default_factory: Callable that returns default value

45

title: Field title for schema

46

description: Field description for schema

47

json_schema_extra: Additional JSON schema data

48

const: Field must have this exact value

49

gt: Greater than constraint (numbers only)

50

ge: Greater than or equal constraint (numbers only)

51

lt: Less than constraint (numbers only)

52

le: Less than or equal constraint (numbers only)

53

multiple_of: Must be multiple of this value (numbers only)

54

min_items: Minimum items in sequence

55

max_items: Maximum items in sequence

56

min_length: Minimum string length

57

max_length: Maximum string length

58

regex: Regular expression pattern for strings

59

examples: Example values for schema

60

61

Returns:

62

Field configuration for use in model definition

63

"""

64

```

65

66

### FieldProxy

67

68

Proxy objects for building queries against model fields.

69

70

```python { .api }

71

class FieldProxy:

72

"""Proxy for model fields enabling query building."""

73

74

def __eq__(self, other):

75

"""Equality comparison for queries."""

76

77

def __ne__(self, other):

78

"""Not equal comparison for queries."""

79

80

def __gt__(self, other):

81

"""Greater than comparison for queries."""

82

83

def __ge__(self, other):

84

"""Greater than or equal comparison for queries."""

85

86

def __lt__(self, other):

87

"""Less than comparison for queries."""

88

89

def __le__(self, other):

90

"""Less than or equal comparison for queries."""

91

```

92

93

## Usage Examples

94

95

### Basic Field Definitions

96

97

```python

98

from odmantic import Model, Field

99

from typing import Optional

100

from datetime import datetime

101

102

class User(Model):

103

# Required field with no default

104

name: str

105

106

# Field with default value

107

is_active: bool = True

108

109

# Field with validation constraints

110

age: int = Field(ge=0, le=150, description="User age in years")

111

112

# Field with unique constraint

113

email: str = Field(unique=True, description="User email address")

114

115

# Field with default factory

116

created_at: datetime = Field(default_factory=datetime.utcnow)

117

118

# Optional field

119

bio: Optional[str] = Field(None, max_length=500)

120

```

121

122

### Custom MongoDB Field Names

123

124

```python

125

class Product(Model):

126

name: str

127

# Python attribute is 'price_usd' but stored as 'price' in MongoDB

128

price_usd: float = Field(key_name="price", gt=0)

129

130

# Python attribute is 'desc' but stored as 'description' in MongoDB

131

desc: str = Field(key_name="description", max_length=1000)

132

```

133

134

### Primary Key Fields

135

136

```python

137

from odmantic import ObjectId

138

import uuid

139

140

# Default ObjectId primary key (automatic)

141

class DefaultPrimary(Model):

142

name: str

143

# id: ObjectId field is automatically created

144

145

# Custom primary key

146

class CustomPrimary(Model):

147

custom_id: str = Field(primary_field=True, default_factory=lambda: str(uuid.uuid4()))

148

name: str

149

# This model uses custom_id as _id in MongoDB

150

151

# ObjectId primary key with custom name

152

class NamedPrimary(Model):

153

user_id: ObjectId = Field(primary_field=True, default_factory=ObjectId)

154

name: str

155

```

156

157

### Index Fields

158

159

```python

160

class SearchableDocument(Model):

161

title: str = Field(index=True) # Regular index

162

slug: str = Field(unique=True) # Unique index

163

content: str

164

tags: list[str] = Field(index=True) # Index on array field

165

166

# Multiple fields with indexes

167

author: str = Field(index=True)

168

category: str = Field(index=True)

169

published_date: datetime = Field(default_factory=datetime.utcnow, index=True)

170

```

171

172

### Validation Fields

173

174

```python

175

from typing import List

176

import re

177

178

class ValidationExample(Model):

179

# String validation

180

username: str = Field(min_length=3, max_length=20, regex=r"^[a-zA-Z0-9_]+$")

181

182

# Numeric validation

183

score: float = Field(ge=0.0, le=100.0, multiple_of=0.1)

184

rating: int = Field(ge=1, le=5)

185

186

# List validation

187

tags: List[str] = Field(min_items=1, max_items=10)

188

189

# Constant value

190

version: str = Field(const="1.0")

191

192

# Example values for documentation

193

status: str = Field(examples=["active", "inactive", "pending"])

194

```

195

196

### Default Value Strategies

197

198

```python

199

from odmantic import Model, Field

200

from datetime import datetime

201

from uuid import uuid4

202

203

class DefaultExamples(Model):

204

# Static default

205

status: str = "pending"

206

207

# Default with Field()

208

priority: int = Field(default=1)

209

210

# Factory function for dynamic defaults

211

created_at: datetime = Field(default_factory=datetime.utcnow)

212

unique_code: str = Field(default_factory=lambda: str(uuid4()))

213

214

# Optional field with None default

215

notes: Optional[str] = Field(default=None)

216

217

# Required field (no default)

218

name: str = Field(...)

219

```

220

221

### Complex Field Examples

222

223

```python

224

from decimal import Decimal

225

from enum import Enum

226

227

class Status(str, Enum):

228

ACTIVE = "active"

229

INACTIVE = "inactive"

230

PENDING = "pending"

231

232

class ComplexModel(Model):

233

# Enum field

234

status: Status = Field(default=Status.PENDING)

235

236

# Decimal field with precision constraints

237

price: Decimal = Field(gt=0, max_digits=10, decimal_places=2)

238

239

# Nested dict with validation

240

metadata: dict[str, str] = Field(default_factory=dict)

241

242

# Complex validation with regex

243

phone: str = Field(regex=r"^\+?1?\d{9,15}$", description="Phone number in international format")

244

245

# List with item constraints

246

scores: List[int] = Field(default_factory=list, min_items=0, max_items=100)

247

```

248

249

### Field Queries

250

251

```python

252

# Fields automatically become FieldProxy objects for queries

253

class User(Model):

254

name: str = Field(index=True)

255

age: int = Field(ge=0)

256

email: str = Field(unique=True)

257

258

# Use fields in queries

259

from odmantic import AIOEngine

260

261

async def query_examples(engine: AIOEngine):

262

# Equality

263

users = await engine.find(User, User.name == "Alice")

264

265

# Comparison

266

adults = await engine.find(User, User.age >= 18)

267

young_adults = await engine.find(User, User.age >= 18, User.age < 30)

268

269

# String matching

270

gmail_users = await engine.find(User, User.email.match(r".*@gmail\.com"))

271

272

# Multiple conditions

273

active_adults = await engine.find(

274

User,

275

User.age >= 18,

276

User.name != "Admin"

277

)

278

```

279

280

### Advanced Field Configuration

281

282

```python

283

from pydantic import field_validator

284

285

class AdvancedModel(Model):

286

# Field with comprehensive configuration

287

name: str = Field(

288

min_length=2,

289

max_length=50,

290

description="Full name of the user",

291

examples=["John Doe", "Jane Smith"],

292

json_schema_extra={"pattern": "^[A-Za-z ]+$"}

293

)

294

295

# Custom validation with field_validator

296

email: str = Field(unique=True, description="User email address")

297

298

@field_validator('email')

299

@classmethod

300

def validate_email(cls, v):

301

if not v or '@' not in v:

302

raise ValueError('Invalid email format')

303

return v.lower().strip()

304

305

# Field with custom MongoDB name and validation

306

account_balance: float = Field(

307

key_name="balance",

308

ge=0.0,

309

description="Account balance in USD",

310

json_schema_extra={"multipleOf": 0.01}

311

)

312

```