0
# ORM Integration
1
2
Specialized factory classes for popular Python ORMs providing database persistence, get-or-create behavior, and ORM-specific features. Factory Boy seamlessly integrates with Django, SQLAlchemy, MongoEngine, and Mogo.
3
4
## Capabilities
5
6
### Django ORM Integration
7
8
Factory classes and helpers specifically designed for Django models with built-in ORM features.
9
10
```python { .api }
11
class DjangoModelFactory(Factory):
12
"""
13
Factory for Django models with ORM integration.
14
15
Meta attributes:
16
- model: Django model class
17
- django_get_or_create: Fields to use for get_or_create behavior (tuple/list)
18
- database: Database alias to use (string)
19
- strategy: Default strategy (inherited from Factory)
20
"""
21
22
@classmethod
23
def _create(cls, model_class, *args, **kwargs):
24
"""Uses Django ORM create() or get_or_create() based on Meta options."""
25
26
class FileField:
27
"""
28
Helper for populating Django FileField instances.
29
30
Args:
31
data (bytes, optional): Raw file content
32
filename (str, optional): Name for the file
33
from_path (str, optional): Path to read file content from
34
from_file (file-like, optional): File object to read from
35
from_func (callable, optional): Function returning file content
36
"""
37
def __init__(self, data=None, filename=None, from_path=None, from_file=None, from_func=None): ...
38
39
class ImageField(FileField):
40
"""
41
Helper for populating Django ImageField instances.
42
43
Args:
44
width (int): Image width in pixels (default: 100)
45
height (int): Image height in pixels (default: 100)
46
color (str): Image color (default: 'blue')
47
format (str): Image format (default: 'JPEG')
48
**kwargs: Additional FileField arguments
49
"""
50
def __init__(self, width=100, height=100, color='blue', format='JPEG', **kwargs): ...
51
52
def mute_signals(*signals):
53
"""
54
Context manager/decorator to disable Django signals during factory operations.
55
56
Args:
57
*signals: Django signal objects to mute
58
59
Returns:
60
Context manager that can also be used as decorator
61
"""
62
```
63
64
#### Usage Examples
65
66
```python
67
from django.db import models
68
from django.contrib.auth.models import User
69
from django.db.models.signals import post_save
70
from factory.django import DjangoModelFactory, FileField, ImageField, mute_signals
71
72
# Django model
73
class Profile(models.Model):
74
user = models.OneToOneField(User, on_delete=models.CASCADE)
75
bio = models.TextField()
76
avatar = models.ImageField(upload_to='avatars/')
77
resume = models.FileField(upload_to='resumes/')
78
79
# Django factory
80
class UserFactory(DjangoModelFactory):
81
class Meta:
82
model = User
83
django_get_or_create = ('username',) # Use get_or_create for username
84
database = 'default' # Optional database alias
85
86
username = Sequence(lambda n: f'user{n}')
87
email = LazyAttribute(lambda obj: f'{obj.username}@example.com')
88
first_name = Faker('first_name')
89
last_name = Faker('last_name')
90
91
class ProfileFactory(DjangoModelFactory):
92
class Meta:
93
model = Profile
94
95
user = SubFactory(UserFactory)
96
bio = Faker('text', max_nb_chars=200)
97
98
# File field with custom content
99
resume = FileField(
100
filename='resume.pdf',
101
data=b'%PDF-1.4 fake pdf content',
102
from_func=lambda: generate_pdf_bytes()
103
)
104
105
# Image field with specifications
106
avatar = ImageField(
107
width=200,
108
height=200,
109
color='red',
110
format='PNG'
111
)
112
113
# Usage
114
user = UserFactory() # Saved to database
115
profile = ProfileFactory() # Creates user and profile
116
117
# Muting signals
118
with mute_signals(post_save):
119
# post_save signals won't fire during this block
120
users = UserFactory.create_batch(10)
121
122
# As decorator
123
@mute_signals(post_save)
124
def create_test_data():
125
return UserFactory.create_batch(100)
126
```
127
128
### SQLAlchemy Integration
129
130
Factory class for SQLAlchemy models with session management and persistence options.
131
132
```python { .api }
133
class SQLAlchemyModelFactory(Factory):
134
"""
135
Factory for SQLAlchemy models with session management.
136
137
Meta attributes:
138
- model: SQLAlchemy model class
139
- sqlalchemy_session: SQLAlchemy session to use
140
- sqlalchemy_session_persistence: Persistence strategy ('commit', 'flush', or None)
141
142
Class attributes:
143
- SESSION_PERSISTENCE_COMMIT = 'commit'
144
- SESSION_PERSISTENCE_FLUSH = 'flush'
145
"""
146
147
SESSION_PERSISTENCE_COMMIT = 'commit'
148
SESSION_PERSISTENCE_FLUSH = 'flush'
149
150
@classmethod
151
def _create(cls, model_class, *args, **kwargs):
152
"""Creates SQLAlchemy instance and manages session persistence."""
153
```
154
155
#### Usage Examples
156
157
```python
158
from sqlalchemy import Column, Integer, String, create_engine
159
from sqlalchemy.ext.declarative import declarative_base
160
from sqlalchemy.orm import sessionmaker
161
from factory.alchemy import SQLAlchemyModelFactory
162
163
# SQLAlchemy setup
164
Base = declarative_base()
165
engine = create_engine('sqlite:///test.db')
166
Session = sessionmaker(bind=engine)
167
session = Session()
168
169
class User(Base):
170
__tablename__ = 'users'
171
id = Column(Integer, primary_key=True)
172
username = Column(String(50))
173
email = Column(String(100))
174
175
# Factory with session management
176
class UserFactory(SQLAlchemyModelFactory):
177
class Meta:
178
model = User
179
sqlalchemy_session = session
180
sqlalchemy_session_persistence = 'commit' # or 'flush' or None
181
182
username = Sequence(lambda n: f'user{n}')
183
email = LazyAttribute(lambda obj: f'{obj.username}@example.com')
184
185
# Usage
186
user = UserFactory() # Created and committed to database
187
users = UserFactory.create_batch(5) # All committed
188
189
# Different persistence strategies
190
class FlushOnlyUserFactory(SQLAlchemyModelFactory):
191
class Meta:
192
model = User
193
sqlalchemy_session = session
194
sqlalchemy_session_persistence = SQLAlchemyModelFactory.SESSION_PERSISTENCE_FLUSH
195
196
username = Sequence(lambda n: f'flush_user{n}')
197
198
# Creates and flushes but doesn't commit
199
user = FlushOnlyUserFactory()
200
```
201
202
### MongoEngine Integration
203
204
Factory class for MongoEngine documents with automatic saving.
205
206
```python { .api }
207
class MongoEngineFactory(Factory):
208
"""
209
Factory for MongoEngine documents with automatic persistence.
210
211
Meta attributes:
212
- model: MongoEngine Document class
213
"""
214
215
@classmethod
216
def _create(cls, model_class, *args, **kwargs):
217
"""Creates MongoEngine document and calls save() if it's a Document."""
218
```
219
220
#### Usage Examples
221
222
```python
223
from mongoengine import Document, StringField, IntField, connect
224
from factory.mongoengine import MongoEngineFactory
225
226
# Connect to MongoDB
227
connect('test_db')
228
229
# MongoEngine model
230
class User(Document):
231
username = StringField(required=True)
232
email = StringField()
233
age = IntField()
234
235
# MongoEngine factory
236
class UserFactory(MongoEngineFactory):
237
class Meta:
238
model = User
239
240
username = Sequence(lambda n: f'user{n}')
241
email = LazyAttribute(lambda obj: f'{obj.username}@example.com')
242
age = Faker('random_int', min=18, max=65)
243
244
# Usage
245
user = UserFactory() # Saved to MongoDB
246
users = UserFactory.create_batch(10) # All saved to MongoDB
247
```
248
249
### Mogo Integration
250
251
Factory class for Mogo (pymongo wrapper) objects.
252
253
```python { .api }
254
class MogoFactory(Factory):
255
"""
256
Factory for Mogo (pymongo wrapper) objects with automatic persistence.
257
258
Meta attributes:
259
- model: Mogo model class
260
"""
261
262
@classmethod
263
def _create(cls, model_class, *args, **kwargs):
264
"""Creates Mogo instance and calls save() method."""
265
```
266
267
#### Usage Examples
268
269
```python
270
from mogo import Model, Field
271
from factory.mogo import MogoFactory
272
273
# Mogo model (assuming mogo is configured)
274
class User(Model):
275
username = Field()
276
email = Field()
277
age = Field()
278
279
# Mogo factory
280
class UserFactory(MogoFactory):
281
class Meta:
282
model = User
283
284
username = Sequence(lambda n: f'user{n}')
285
email = LazyAttribute(lambda obj: f'{obj.username}@example.com')
286
age = Faker('random_int', min=18, max=65)
287
288
# Usage
289
user = UserFactory() # Saved via mogo
290
```
291
292
## Common ORM Integration Patterns
293
294
### Database-Specific Factories
295
296
```python
297
# Multiple database support (Django)
298
class PrimaryDBUserFactory(DjangoModelFactory):
299
class Meta:
300
model = User
301
database = 'primary'
302
303
class AnalyticsDBUserFactory(DjangoModelFactory):
304
class Meta:
305
model = User
306
database = 'analytics'
307
```
308
309
### Get-or-Create Behavior
310
311
```python
312
# Django get_or_create
313
class CategoryFactory(DjangoModelFactory):
314
class Meta:
315
model = Category
316
django_get_or_create = ('name',) # Won't create duplicates by name
317
318
name = Iterator(['Technology', 'Sports', 'News'])
319
slug = LazyAttribute(lambda obj: slugify(obj.name))
320
321
# Always returns existing or creates new based on name
322
tech_category = CategoryFactory(name='Technology') # Gets existing or creates
323
```
324
325
### Transaction Management
326
327
```python
328
# SQLAlchemy with custom session handling
329
from sqlalchemy.orm import scoped_session
330
331
class TransactionalUserFactory(SQLAlchemyModelFactory):
332
class Meta:
333
model = User
334
sqlalchemy_session = scoped_session(sessionmaker())
335
sqlalchemy_session_persistence = None # Manual control
336
337
username = Sequence(lambda n: f'user{n}')
338
339
@classmethod
340
def _create(cls, model_class, *args, **kwargs):
341
instance = super()._create(model_class, *args, **kwargs)
342
# Custom transaction logic
343
cls._meta.sqlalchemy_session.add(instance)
344
return instance
345
```
346
347
### File and Media Handling
348
349
```python
350
# Django with custom file handling
351
class DocumentFactory(DjangoModelFactory):
352
class Meta:
353
model = Document
354
355
title = Faker('sentence')
356
357
# Generate PDF content dynamically
358
file = FileField(
359
filename=LazyAttribute(lambda obj: f'{slugify(obj.title)}.pdf'),
360
from_func=lambda: generate_pdf_content()
361
)
362
363
# Image with dynamic dimensions
364
thumbnail = ImageField(
365
width=LazyFunction(lambda: random.randint(100, 300)),
366
height=LazyFunction(lambda: random.randint(100, 300)),
367
format='PNG'
368
)
369
```
370
371
### Signal Management
372
373
```python
374
# Complex signal muting
375
from django.db.models.signals import post_save, pre_save, post_delete
376
377
@mute_signals(post_save, pre_save, post_delete)
378
class SilentUserFactory(DjangoModelFactory):
379
class Meta:
380
model = User
381
382
username = Sequence(lambda n: f'silent_user{n}')
383
384
# Conditional signal muting
385
def create_users_silently(count):
386
with mute_signals(post_save):
387
return UserFactory.create_batch(count)
388
```