or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

connections.mddjango-integration.mddocument-operations.mderror-handling.mdfabric-support.mdindex.mdsql-operations.md

django-integration.mddocs/

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

```