or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

adapter-configuration.mddrizzle-integration.mdindex.mdmigration-system.md

drizzle-integration.mddocs/

0

# Drizzle Integration

1

2

Direct access to Drizzle ORM functionality for advanced database operations, custom queries, and low-level database management. The adapter provides seamless integration with Drizzle ORM while maintaining Payload's abstraction layer.

3

4

## Capabilities

5

6

### Core Drizzle Access

7

8

Access to the complete Drizzle ORM functionality through re-exported modules.

9

10

```typescript { .api }

11

/**

12

* Main Drizzle ORM module re-export

13

* Provides access to core Drizzle functionality including SQL template literals,

14

* query builders, and utility functions

15

*/

16

import * as drizzle from "@payloadcms/db-sqlite/drizzle";

17

18

/**

19

* SQL template literal function for raw query construction

20

* Provides type-safe parameter binding and query building

21

*/

22

import { sql } from "@payloadcms/db-sqlite";

23

```

24

25

**Usage Examples:**

26

27

```typescript

28

import { sql } from "@payloadcms/db-sqlite";

29

import * as drizzle from "@payloadcms/db-sqlite/drizzle";

30

31

// In a migration or custom operation

32

export async function customQuery({ db }: { db: any }) {

33

// Raw SQL with parameters

34

const result = await db.run(sql`

35

SELECT COUNT(*) as total

36

FROM posts

37

WHERE status = ${'published'}

38

`);

39

40

// Using Drizzle query builder methods

41

const { eq, and, or } = drizzle;

42

43

// Complex conditional queries

44

const complexQuery = sql`

45

SELECT * FROM users

46

WHERE ${and(

47

eq(sql`active`, true),

48

or(

49

eq(sql`role`, 'admin'),

50

eq(sql`role`, 'editor')

51

)

52

)}

53

`;

54

}

55

```

56

57

### SQLite Core Integration

58

59

Access to SQLite-specific Drizzle functionality for table definitions, column types, and database operations.

60

61

```typescript { .api }

62

/**

63

* SQLite-specific Drizzle ORM functionality

64

* Includes table creation, column definitions, and SQLite-specific features

65

*/

66

import * as sqliteCore from "@payloadcms/db-sqlite/drizzle/sqlite-core";

67

```

68

69

**Usage Examples:**

70

71

```typescript

72

import * as sqliteCore from "@payloadcms/db-sqlite/drizzle/sqlite-core";

73

74

// In schema hooks or custom table definitions

75

const {

76

sqliteTable,

77

text,

78

integer,

79

real,

80

blob,

81

primaryKey,

82

foreignKey,

83

unique,

84

index

85

} = sqliteCore;

86

87

// Custom table definition

88

const customTable = sqliteTable('custom_analytics', {

89

id: integer('id').primaryKey({ autoIncrement: true }),

90

event_name: text('event_name').notNull(),

91

user_id: integer('user_id').references(() => usersTable.id),

92

timestamp: integer('timestamp').notNull(),

93

metadata: text('metadata', { mode: 'json' }),

94

value: real('value'),

95

}, (table) => ({

96

// Composite indexes

97

eventUserIdx: index('event_user_idx').on(table.event_name, table.user_id),

98

timestampIdx: index('timestamp_idx').on(table.timestamp),

99

// Unique constraints

100

uniqueEventUser: unique('unique_event_user').on(table.event_name, table.user_id, table.timestamp),

101

}));

102

```

103

104

### LibSQL Client Integration

105

106

Direct access to LibSQL-specific functionality for Turso databases and edge deployments.

107

108

```typescript { .api }

109

/**

110

* LibSQL-specific Drizzle integration

111

* Provides access to LibSQL client features and remote database functionality

112

*/

113

import * as libsql from "@payloadcms/db-sqlite/drizzle/libsql";

114

```

115

116

**Usage Examples:**

117

118

```typescript

119

import * as libsql from "@payloadcms/db-sqlite/drizzle/libsql";

120

121

// Access LibSQL-specific features

122

const { createClient } = libsql;

123

124

// Custom LibSQL client configuration (if needed)

125

export function createCustomClient() {

126

return createClient({

127

url: process.env.TURSO_DATABASE_URL!,

128

authToken: process.env.TURSO_AUTH_TOKEN!,

129

// LibSQL-specific options

130

syncUrl: process.env.TURSO_SYNC_URL,

131

syncInterval: 5000,

132

});

133

}

134

```

135

136

### Relations and Foreign Keys

137

138

Access to Drizzle's relation system for defining and managing database relationships.

139

140

```typescript { .api }

141

/**

142

* Drizzle relations system for defining table relationships

143

* Enables type-safe joins and relationship queries

144

*/

145

import * as relations from "@payloadcms/db-sqlite/drizzle/relations";

146

```

147

148

**Usage Examples:**

149

150

```typescript

151

import * as relations from "@payloadcms/db-sqlite/drizzle/relations";

152

import { sqliteTable, integer, text } from "@payloadcms/db-sqlite/drizzle/sqlite-core";

153

154

const { relations, one, many } = relations;

155

156

// Define tables

157

const users = sqliteTable('users', {

158

id: integer('id').primaryKey(),

159

name: text('name').notNull(),

160

});

161

162

const posts = sqliteTable('posts', {

163

id: integer('id').primaryKey(),

164

title: text('title').notNull(),

165

authorId: integer('author_id').references(() => users.id),

166

});

167

168

// Define relations

169

const usersRelations = relations(users, ({ many }) => ({

170

posts: many(posts),

171

}));

172

173

const postsRelations = relations(posts, ({ one }) => ({

174

author: one(users, {

175

fields: [posts.authorId],

176

references: [users.id],

177

}),

178

}));

179

180

// Use in queries (within migrations or hooks)

181

export async function getPostsWithAuthors({ db }: { db: any }) {

182

return await db.query.posts.findMany({

183

with: {

184

author: true,

185

},

186

});

187

}

188

```

189

190

### Advanced Query Building

191

192

Complex query construction using Drizzle's query builder with SQLite optimizations.

193

194

```typescript { .api }

195

/**

196

* Advanced query building utilities

197

* Provides access to Drizzle's full query construction capabilities

198

*/

199

interface DrizzleQueryBuilder {

200

/** Conditional operators for WHERE clauses */

201

eq: (column: any, value: any) => any;

202

ne: (column: any, value: any) => any;

203

gt: (column: any, value: any) => any;

204

gte: (column: any, value: any) => any;

205

lt: (column: any, value: any) => any;

206

lte: (column: any, value: any) => any;

207

like: (column: any, pattern: string) => any;

208

notLike: (column: any, pattern: string) => any;

209

isNull: (column: any) => any;

210

isNotNull: (column: any) => any;

211

inArray: (column: any, values: any[]) => any;

212

notInArray: (column: any, values: any[]) => any;

213

214

/** Logical operators */

215

and: (...conditions: any[]) => any;

216

or: (...conditions: any[]) => any;

217

not: (condition: any) => any;

218

219

/** Aggregation functions */

220

count: (column?: any) => any;

221

sum: (column: any) => any;

222

avg: (column: any) => any;

223

min: (column: any) => any;

224

max: (column: any) => any;

225

}

226

```

227

228

**Usage Examples:**

229

230

```typescript

231

import { sql } from "@payloadcms/db-sqlite";

232

import { eq, and, or, count, sum } from "@payloadcms/db-sqlite/drizzle";

233

234

// In custom operations or hooks

235

export async function advancedQueries({ db, schema }: { db: any, schema: any }) {

236

const { posts, users } = schema.tables;

237

238

// Complex filtering

239

const activeUserPosts = await db

240

.select({

241

id: posts.id,

242

title: posts.title,

243

authorName: users.name,

244

})

245

.from(posts)

246

.innerJoin(users, eq(posts.authorId, users.id))

247

.where(

248

and(

249

eq(posts.status, 'published'),

250

or(

251

eq(users.role, 'admin'),

252

eq(users.role, 'editor')

253

),

254

isNotNull(posts.featuredImage)

255

)

256

)

257

.orderBy(posts.createdAt)

258

.limit(10);

259

260

// Aggregation queries

261

const postStats = await db

262

.select({

263

authorId: posts.authorId,

264

authorName: users.name,

265

postCount: count(posts.id),

266

totalViews: sum(posts.viewCount),

267

avgRating: avg(posts.rating),

268

})

269

.from(posts)

270

.innerJoin(users, eq(posts.authorId, users.id))

271

.groupBy(posts.authorId, users.name)

272

.having(gt(count(posts.id), 5));

273

274

// Subqueries

275

const topAuthors = db

276

.select({ id: users.id })

277

.from(users)

278

.where(

279

inArray(

280

users.id,

281

db

282

.select({ authorId: posts.authorId })

283

.from(posts)

284

.groupBy(posts.authorId)

285

.having(gt(count(posts.id), 10))

286

)

287

);

288

289

return { activeUserPosts, postStats, topAuthors };

290

}

291

```

292

293

### Transaction Management

294

295

Direct access to Drizzle's transaction capabilities for complex operations.

296

297

```typescript { .api }

298

/**

299

* Transaction management utilities

300

* Provides low-level transaction control for complex operations

301

*/

302

interface DrizzleTransactions {

303

/** Execute operations within a transaction */

304

transaction: <T>(

305

callback: (tx: any) => Promise<T>

306

) => Promise<T>;

307

}

308

```

309

310

**Usage Examples:**

311

312

```typescript

313

import { sql } from "@payloadcms/db-sqlite";

314

315

// Complex transaction with multiple operations

316

export async function complexTransaction({ db }: { db: any }) {

317

return await db.transaction(async (tx) => {

318

// Create user

319

const [user] = await tx

320

.insert(users)

321

.values({ name: 'John Doe', email: 'john@example.com' })

322

.returning();

323

324

// Create profile

325

await tx

326

.insert(profiles)

327

.values({

328

userId: user.id,

329

bio: 'Software developer',

330

avatar: 'avatar.jpg'

331

});

332

333

// Update statistics

334

await tx.run(sql`

335

UPDATE site_stats

336

SET user_count = user_count + 1,

337

updated_at = CURRENT_TIMESTAMP

338

`);

339

340

// Send welcome email (external service)

341

await sendWelcomeEmail(user.email);

342

343

return user;

344

});

345

}

346

```

347

348

### Custom Operators

349

350

Access to SQLite-specific operators and functions through Drizzle integration.

351

352

```typescript { .api }

353

/**

354

* SQLite-specific operators and functions

355

* Optimized for SQLite's case-insensitive LIKE behavior

356

*/

357

interface SQLiteOperators {

358

/** Case-insensitive LIKE (native SQLite behavior) */

359

like: (column: any, pattern: string) => any;

360

/** Case-insensitive NOT LIKE */

361

notLike: (column: any, pattern: string) => any;

362

/** JSON operations for JSON columns */

363

jsonExtract: (column: any, path: string) => any;

364

jsonArrayLength: (column: any) => any;

365

}

366

```

367

368

**Usage Examples:**

369

370

```typescript

371

import { like, notLike } from "@payloadcms/db-sqlite/drizzle";

372

import { sql } from "@payloadcms/db-sqlite";

373

374

// SQLite-optimized queries

375

export async function searchOperations({ db, schema }: { db: any, schema: any }) {

376

const { posts } = schema.tables;

377

378

// Case-insensitive search (SQLite's native LIKE behavior)

379

const searchResults = await db

380

.select()

381

.from(posts)

382

.where(

383

or(

384

like(posts.title, '%javascript%'),

385

like(posts.content, '%typescript%')

386

)

387

);

388

389

// JSON operations

390

const postsWithTags = await db

391

.select({

392

id: posts.id,

393

title: posts.title,

394

tagCount: sql`json_array_length(${posts.metadata}, '$.tags')`,

395

firstTag: sql`json_extract(${posts.metadata}, '$.tags[0]')`,

396

})

397

.from(posts)

398

.where(sql`json_extract(${posts.metadata}, '$.tags') IS NOT NULL`);

399

400

return { searchResults, postsWithTags };

401

}

402

```