0
# Django Integration
1
2
Complete Django ORM backend providing seamless integration with Django applications, including database introspection, feature detection, and operation optimization.
3
4
## Capabilities
5
6
### Database Backend
7
8
Django database backend implementation for MySQL Connector Python.
9
10
```python { .api }
11
class DatabaseWrapper:
12
"""
13
Django database backend wrapper for MySQL Connector Python.
14
15
Provides complete Django ORM integration with MySQL databases,
16
supporting all Django database features including migrations,
17
transactions, and query optimization.
18
"""
19
20
def __init__(self, settings_dict, alias='default'):
21
"""
22
Initialize database wrapper.
23
24
Parameters:
25
- settings_dict (dict): Database configuration from Django settings
26
- alias (str): Database alias name
27
"""
28
29
def get_connection_params(self):
30
"""
31
Get connection parameters from Django settings.
32
33
Returns:
34
dict: MySQL Connector connection parameters
35
"""
36
37
def get_new_connection(self, conn_params):
38
"""
39
Create new database connection.
40
41
Parameters:
42
- conn_params (dict): Connection parameters
43
44
Returns:
45
MySQLConnection: Database connection object
46
"""
47
48
def init_connection_state(self):
49
"""Initialize connection state for Django requirements"""
50
51
def create_cursor(self, name=None):
52
"""
53
Create database cursor.
54
55
Parameters:
56
- name (str): Cursor name (unused)
57
58
Returns:
59
CursorWrapper: Django cursor wrapper
60
"""
61
62
def _set_autocommit(self, autocommit):
63
"""Set connection autocommit mode"""
64
65
def disable_constraint_checking(self):
66
"""Disable foreign key constraint checking"""
67
68
def enable_constraint_checking(self):
69
"""Enable foreign key constraint checking"""
70
71
def check_constraints(self, table_names=None):
72
"""Check integrity constraints"""
73
74
def is_usable(self):
75
"""Check if connection is still usable"""
76
77
@property
78
def queries_limit(self):
79
"""Query limit for debug logging"""
80
81
@property
82
def queries_logged(self):
83
"""Number of queries logged"""
84
```
85
86
### Database Features
87
88
Detection and configuration of MySQL-specific database features.
89
90
```python { .api }
91
class DatabaseFeatures:
92
"""
93
Database feature detection and configuration for MySQL.
94
95
Defines which Django features are supported by MySQL and
96
provides MySQL-specific behavior configuration.
97
"""
98
99
# Feature flags
100
empty_fetchmany_value = ()
101
update_can_self_select = False
102
allows_group_by_pk = True
103
related_fields_match_type = True
104
allow_sliced_subqueries = False
105
has_bulk_insert = True
106
has_select_for_update = True
107
has_select_for_update_nowait = False
108
supports_forward_references = True
109
supports_long_model_names = False
110
supports_microsecond_precision = False
111
supports_regex_backreferencing = False
112
supports_date_lookup_using_string = False
113
can_introspect_autofield = True
114
can_introspect_binary_field = False
115
can_introspect_boolean_field = False
116
can_introspect_null = True
117
can_introspect_positive_integer_field = True
118
can_introspect_small_integer_field = True
119
supports_timezones = False
120
requires_explicit_null_ordering_when_grouping = True
121
allows_auto_pk_0 = False
122
uses_savepoints = True
123
atomic_transactions = False
124
125
def __init__(self, connection):
126
"""Initialize with database connection"""
127
self.connection = connection
128
129
@cached_property
130
def supports_transactions(self):
131
"""Check if MySQL storage engine supports transactions"""
132
133
@cached_property
134
def has_zoneinfo_database(self):
135
"""Check if MySQL has timezone database loaded"""
136
137
@cached_property
138
def supports_over_clause(self):
139
"""Check if MySQL version supports window functions"""
140
141
@cached_property
142
def supports_frame_range_fixed_distance(self):
143
"""Check window function frame support"""
144
```
145
146
### Database Operations
147
148
MySQL-specific database operations and SQL generation.
149
150
```python { .api }
151
class DatabaseOperations:
152
"""
153
MySQL-specific database operations and SQL generation.
154
155
Provides MySQL-specific implementations of database operations
156
required by Django ORM, including SQL quoting, date formatting,
157
and aggregate functions.
158
"""
159
160
compiler_module = "mysql.connector.django.compiler"
161
162
def __init__(self, connection):
163
"""Initialize with database connection"""
164
self.connection = connection
165
166
def autoinc_sql(self, table, column):
167
"""
168
Generate auto-increment SQL for column.
169
170
Parameters:
171
- table (str): Table name
172
- column (str): Column name
173
174
Returns:
175
str: AUTO_INCREMENT SQL
176
"""
177
return "AUTO_INCREMENT"
178
179
def bulk_batch_size(self, fields, objs):
180
"""
181
Calculate optimal batch size for bulk operations.
182
183
Parameters:
184
- fields (list): Field list
185
- objs (list): Object list
186
187
Returns:
188
int: Optimal batch size
189
"""
190
191
def quote_name(self, name):
192
"""
193
Quote database identifier name.
194
195
Parameters:
196
- name (str): Database identifier
197
198
Returns:
199
str: Quoted identifier
200
"""
201
return "`%s`" % name.replace("`", "``")
202
203
def random_function_sql(self):
204
"""Get SQL for random number generation"""
205
return "RAND()"
206
207
def sql_flush(self, style, tables, sequences, allow_cascade=False):
208
"""
209
Generate SQL to flush database tables.
210
211
Parameters:
212
- style: SQL style formatter
213
- tables (list): Table names to flush
214
- sequences (list): Sequence names to reset
215
- allow_cascade (bool): Allow cascading deletes
216
217
Returns:
218
list: SQL statements
219
"""
220
221
def validate_autopk_value(self, value):
222
"""Validate auto primary key value"""
223
return 0 < value < 18446744073709551616
224
225
def adapt_datetimefield_value(self, value):
226
"""Adapt datetime value for MySQL storage"""
227
228
def adapt_timefield_value(self, value):
229
"""Adapt time value for MySQL storage"""
230
231
def date_extract_sql(self, lookup_type, field_name):
232
"""Generate SQL for date extraction"""
233
234
def date_trunc_sql(self, lookup_type, field_name):
235
"""Generate SQL for date truncation"""
236
237
def datetime_extract_sql(self, lookup_type, field_name, tzname):
238
"""Generate SQL for datetime extraction"""
239
240
def datetime_trunc_sql(self, lookup_type, field_name, tzname):
241
"""Generate SQL for datetime truncation"""
242
243
def time_extract_sql(self, lookup_type, field_name):
244
"""Generate SQL for time extraction"""
245
246
def force_no_ordering(self):
247
"""Get SQL to force no result ordering"""
248
return [(None, ("NULL", [], False))]
249
250
def fulltext_search_sql(self, field_name):
251
"""Generate SQL for full-text search"""
252
return "MATCH (%s) AGAINST (%%s IN BOOLEAN MODE)" % field_name
253
254
def last_insert_id(self, cursor, table_name, pk_name):
255
"""Get last inserted row ID"""
256
return cursor.lastrowid
257
258
def lookup_cast(self, lookup_type, internal_type=None):
259
"""Get SQL cast for field lookup"""
260
261
def max_name_length(self):
262
"""Maximum identifier name length"""
263
return 64
264
265
def pk_default_value(self):
266
"""Default primary key value"""
267
return "NULL"
268
269
def prep_for_iexact_query(self, x):
270
"""Prepare value for case-insensitive exact lookup"""
271
return x
272
273
def process_clob(self, value):
274
"""Process CLOB field value"""
275
return value
276
277
def regex_lookup(self, lookup_type):
278
"""Get SQL operator for regex lookup"""
279
if lookup_type == 'regex':
280
return '%s REGEXP BINARY %s'
281
else:
282
return '%s REGEXP %s'
283
284
def savepoint_create_sql(self, sid):
285
"""Generate SQL to create savepoint"""
286
return "SAVEPOINT %s" % self.quote_name(sid)
287
288
def savepoint_rollback_sql(self, sid):
289
"""Generate SQL to rollback to savepoint"""
290
return "ROLLBACK TO SAVEPOINT %s" % self.quote_name(sid)
291
292
def savepoint_commit_sql(self, sid):
293
"""Generate SQL to release savepoint"""
294
return "RELEASE SAVEPOINT %s" % self.quote_name(sid)
295
```
296
297
### Database Introspection
298
299
Schema introspection capabilities for Django migrations and admin.
300
301
```python { .api }
302
class DatabaseIntrospection:
303
"""
304
Database schema introspection for Django migrations and admin.
305
306
Provides methods to inspect existing database schema and
307
extract metadata for Django model generation and migrations.
308
"""
309
310
data_types_reverse = {
311
FIELD_TYPE.BLOB: 'TextField',
312
FIELD_TYPE.CHAR: 'CharField',
313
FIELD_TYPE.DECIMAL: 'DecimalField',
314
FIELD_TYPE.NEWDECIMAL: 'DecimalField',
315
FIELD_TYPE.DATE: 'DateField',
316
FIELD_TYPE.DATETIME: 'DateTimeField',
317
FIELD_TYPE.DOUBLE: 'FloatField',
318
FIELD_TYPE.FLOAT: 'FloatField',
319
FIELD_TYPE.INT24: 'IntegerField',
320
FIELD_TYPE.LONG: 'IntegerField',
321
FIELD_TYPE.LONGLONG: 'BigIntegerField',
322
FIELD_TYPE.SHORT: 'SmallIntegerField',
323
FIELD_TYPE.STRING: 'CharField',
324
FIELD_TYPE.TIMESTAMP: 'DateTimeField',
325
FIELD_TYPE.TINY: 'IntegerField',
326
FIELD_TYPE.TINY_BLOB: 'TextField',
327
FIELD_TYPE.MEDIUM_BLOB: 'TextField',
328
FIELD_TYPE.LONG_BLOB: 'TextField',
329
FIELD_TYPE.VAR_STRING: 'CharField',
330
FIELD_TYPE.VARCHAR: 'CharField',
331
FIELD_TYPE.TIME: 'TimeField',
332
FIELD_TYPE.YEAR: 'IntegerField',
333
}
334
335
def __init__(self, connection):
336
"""Initialize with database connection"""
337
self.connection = connection
338
339
def get_table_list(self, cursor):
340
"""
341
Get list of tables in database.
342
343
Parameters:
344
- cursor: Database cursor
345
346
Returns:
347
list: Table information tuples
348
"""
349
350
def get_table_description(self, cursor, table_name):
351
"""
352
Get column descriptions for table.
353
354
Parameters:
355
- cursor: Database cursor
356
- table_name (str): Table name
357
358
Returns:
359
list: Column description tuples
360
"""
361
362
def get_relations(self, cursor, table_name):
363
"""
364
Get foreign key relations for table.
365
366
Parameters:
367
- cursor: Database cursor
368
- table_name (str): Table name
369
370
Returns:
371
dict: Column to referenced table/column mapping
372
"""
373
374
def get_key_columns(self, cursor, table_name):
375
"""
376
Get foreign key column information.
377
378
Parameters:
379
- cursor: Database cursor
380
- table_name (str): Table name
381
382
Returns:
383
list: Foreign key column information
384
"""
385
386
def get_indexes(self, cursor, table_name):
387
"""
388
Get index information for table.
389
390
Parameters:
391
- cursor: Database cursor
392
- table_name (str): Table name
393
394
Returns:
395
dict: Index information mapping
396
"""
397
398
def get_constraints(self, cursor, table_name):
399
"""
400
Get constraint information for table.
401
402
Parameters:
403
- cursor: Database cursor
404
- table_name (str): Table name
405
406
Returns:
407
dict: Constraint information mapping
408
"""
409
410
def data_type_check_constraints(self, field_type):
411
"""Get check constraints for field type"""
412
413
def describe_table(self, cursor, table_name):
414
"""Get detailed table description"""
415
```
416
417
### Django Settings Configuration
418
419
Django settings configuration for MySQL Connector Python backend.
420
421
```python { .api }
422
# Django settings.py configuration example
423
DATABASES = {
424
'default': {
425
'ENGINE': 'mysql.connector.django',
426
'NAME': 'django_db',
427
'USER': 'django_user',
428
'PASSWORD': 'django_password',
429
'HOST': 'localhost',
430
'PORT': 3306,
431
'OPTIONS': {
432
'autocommit': True,
433
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
434
'charset': 'utf8mb4',
435
'use_unicode': True,
436
'sql_mode': 'STRICT_TRANS_TABLES',
437
'isolation_level': 'read committed',
438
},
439
}
440
}
441
```
442
443
**Usage Example:**
444
445
```python
446
# Django model using MySQL-specific features
447
from django.db import models
448
449
class User(models.Model):
450
name = models.CharField(max_length=100)
451
email = models.EmailField(unique=True)
452
created_at = models.DateTimeField(auto_now_add=True)
453
bio = models.TextField(blank=True)
454
455
class Meta:
456
db_table = 'users'
457
indexes = [
458
models.Index(fields=['email']),
459
models.Index(fields=['created_at']),
460
]
461
462
# Django ORM queries work seamlessly
463
users = User.objects.filter(created_at__year=2023)
464
User.objects.bulk_create([
465
User(name='John', email='john@example.com'),
466
User(name='Jane', email='jane@example.com'),
467
])
468
469
# Raw SQL with Django
470
from django.db import connection
471
472
with connection.cursor() as cursor:
473
cursor.execute("SELECT COUNT(*) FROM users WHERE created_at > %s", ['2023-01-01'])
474
count = cursor.fetchone()[0]
475
```
476
477
## Types
478
479
```python { .api }
480
DjangoSettings = {
481
'ENGINE': str,
482
'NAME': str,
483
'USER': str,
484
'PASSWORD': str,
485
'HOST': str,
486
'PORT': int,
487
'OPTIONS': dict[str, any]
488
}
489
490
TableInfo = tuple[str, str] # (table_name, table_type)
491
492
ColumnDescription = tuple[
493
str, # column_name
494
str, # data_type
495
int, # display_size
496
int, # internal_size
497
int, # precision
498
int, # scale
499
bool # null_ok
500
]
501
502
IndexInfo = {
503
'columns': list[str],
504
'primary_key': bool,
505
'unique': bool,
506
'foreign_key': tuple[str, str] or None,
507
'check': bool,
508
'type': str,
509
'orders': list[str]
510
}
511
```