or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

expression-builders.mdgraph-operations.mdindex.mdmodel-definition.mdquery-building.mdrelationships.mdtransactions.mdutilities.mdvalidation.md

graph-operations.mddocs/

0

# Graph Operations

1

2

Insert, update, and upsert operations for complex nested data structures with relationship handling.

3

4

## Capabilities

5

6

### Insert Graph

7

8

Insert a model graph with nested relations in a single operation.

9

10

```javascript { .api }

11

/**

12

* Insert a graph of models with their relations

13

* @param graph - Object or array of objects representing the model graph

14

* @param options - Insert graph options

15

* @returns QueryBuilder instance

16

*/

17

insertGraph(graph: object | object[], options?: InsertGraphOptions): QueryBuilder;

18

19

/**

20

* Insert graph and return the inserted models

21

* @param graph - Object or array representing the model graph

22

* @param options - Insert graph options

23

* @returns QueryBuilder instance

24

*/

25

insertGraphAndFetch(graph: object | object[], options?: InsertGraphOptions): QueryBuilder;

26

27

interface InsertGraphOptions {

28

relate?: boolean | string[];

29

allowRefs?: boolean;

30

}

31

```

32

33

**Usage Examples:**

34

35

```javascript

36

// Insert person with pets

37

const graph = {

38

firstName: 'John',

39

lastName: 'Doe',

40

pets: [

41

{ name: 'Fluffy', species: 'cat' },

42

{ name: 'Buddy', species: 'dog' }

43

]

44

};

45

46

const inserted = await Person.query()

47

.insertGraphAndFetch(graph);

48

49

// Insert with existing relations (relate option)

50

const graphWithExistingMovie = {

51

firstName: 'Jane',

52

lastName: 'Smith',

53

movies: [

54

{ id: 1 }, // Existing movie to relate

55

{ title: 'New Movie', year: 2023 } // New movie to insert

56

]

57

};

58

59

await Person.query()

60

.insertGraph(graphWithExistingMovie, { relate: true });

61

62

// Insert with references

63

const graphWithRefs = {

64

firstName: 'Alice',

65

lastName: 'Johnson',

66

pets: [

67

{ '#id': 'fluffy', name: 'Fluffy', species: 'cat' },

68

{ name: 'Buddy', species: 'dog', bestFriend: { '#ref': 'fluffy' } }

69

]

70

};

71

72

await Person.query()

73

.insertGraph(graphWithRefs, { allowRefs: true });

74

```

75

76

### Upsert Graph

77

78

Insert or update a model graph, handling both new and existing models.

79

80

```javascript { .api }

81

/**

82

* Upsert (insert or update) a graph of models

83

* @param graph - Object or array representing the model graph

84

* @param options - Upsert graph options

85

* @returns QueryBuilder instance

86

*/

87

upsertGraph(graph: object | object[], options?: UpsertGraphOptions): QueryBuilder;

88

89

/**

90

* Upsert graph and return the resulting models

91

* @param graph - Object or array representing the model graph

92

* @param options - Upsert graph options

93

* @returns QueryBuilder instance

94

*/

95

upsertGraphAndFetch(graph: object | object[], options?: UpsertGraphOptions): QueryBuilder;

96

97

interface UpsertGraphOptions {

98

relate?: boolean | string[];

99

unrelate?: boolean | string[];

100

insertMissing?: boolean | string[];

101

update?: boolean | string[];

102

noInsert?: boolean | string[];

103

noUpdate?: boolean | string[];

104

noDelete?: boolean | string[];

105

noRelate?: boolean | string[];

106

noUnrelate?: boolean | string[];

107

allowRefs?: boolean;

108

}

109

```

110

111

**Usage Examples:**

112

113

```javascript

114

// Basic upsert - update person, insert/update pets

115

const graph = {

116

id: 1, // Existing person

117

firstName: 'John Updated',

118

pets: [

119

{ id: 1, name: 'Fluffy Updated' }, // Update existing pet

120

{ name: 'New Pet', species: 'bird' } // Insert new pet

121

]

122

};

123

124

const result = await Person.query()

125

.upsertGraphAndFetch(graph);

126

127

// Upsert with relation control

128

const graphWithOptions = {

129

id: 1,

130

firstName: 'John',

131

pets: [

132

{ id: 1, name: 'Fluffy' },

133

{ id: 2, name: 'Buddy' }

134

],

135

movies: [

136

{ id: 5 } // Existing movie to relate

137

]

138

};

139

140

await Person.query()

141

.upsertGraph(graphWithOptions, {

142

relate: ['movies'], // Only relate movies, don't update them

143

unrelate: ['movies'], // Unrelate movies not in the graph

144

update: ['pets'], // Allow updating pets

145

insertMissing: ['pets'] // Insert missing pets

146

});

147

148

// Prevent certain operations

149

await Person.query()

150

.upsertGraph(graph, {

151

noDelete: true, // Don't delete related models not in graph

152

noUpdate: ['movies'], // Don't update movies

153

noInsert: ['movies'] // Don't insert new movies

154

});

155

```

156

157

### Graph Expression Object

158

159

Convert relation expressions to object format for programmatic manipulation.

160

161

```javascript { .api }

162

/**

163

* Get the graph expression as an object

164

* @returns Object representation of the graph expression

165

*/

166

graphExpressionObject(): object;

167

```

168

169

### Graph References

170

171

Special properties for creating references within graphs.

172

173

```javascript { .api }

174

// Special graph properties

175

interface GraphParameters {

176

'#dbRef'?: any; // Reference to existing database record

177

'#ref'?: string; // Reference to another object in the graph

178

'#id'?: string; // ID for this object to be referenced by others

179

}

180

```

181

182

**Usage Examples:**

183

184

```javascript

185

// Using #dbRef to reference existing records

186

const graph = {

187

firstName: 'John',

188

pets: [

189

{ '#dbRef': 1 }, // Reference existing pet with ID 1

190

{ name: 'New Pet', species: 'cat' }

191

]

192

};

193

194

// Using #ref and #id for internal references

195

const graph = {

196

firstName: 'Jane',

197

pets: [

198

{

199

'#id': 'pet1',

200

name: 'Fluffy',

201

species: 'cat'

202

},

203

{

204

name: 'Buddy',

205

species: 'dog',

206

playmate: { '#ref': 'pet1' } // Reference to Fluffy

207

}

208

]

209

};

210

```

211

212

### Allow Graph

213

214

Restrict which relations can be inserted/updated in graph operations.

215

216

```javascript { .api }

217

/**

218

* Allow only specific relations in graph operations

219

* @param expression - Relation expression specifying allowed relations

220

* @returns QueryBuilder instance

221

*/

222

allowGraph(expression: string): QueryBuilder;

223

```

224

225

**Usage Examples:**

226

227

```javascript

228

// Only allow inserting pets, not movies

229

await Person.query()

230

.allowGraph('pets')

231

.insertGraph({

232

firstName: 'John',

233

pets: [{ name: 'Fluffy', species: 'cat' }],

234

movies: [{ title: 'Movie' }] // This will be ignored

235

});

236

237

// Allow nested relations

238

await Person.query()

239

.allowGraph('pets.owner.movies')

240

.insertGraph(complexGraph);

241

242

// Allow multiple relations

243

await Person.query()

244

.allowGraph('[pets, movies.actors]')

245

.insertGraph(graph);

246

```

247

248

### Graph Validation

249

250

Control validation during graph operations.

251

252

```javascript { .api }

253

// Options that affect validation

254

interface GraphOperationOptions {

255

skipValidation?: boolean; // Skip JSON schema validation

256

}

257

```

258

259

**Usage Examples:**

260

261

```javascript

262

// Skip validation for performance

263

await Person.query()

264

.insertGraph(largeGraph, {

265

skipValidation: true

266

});

267

```

268

269

### Transaction Integration

270

271

Graph operations work seamlessly with transactions.

272

273

**Usage Examples:**

274

275

```javascript

276

await Person.transaction(async trx => {

277

// All graph operations will be in the same transaction

278

const person = await Person.query(trx)

279

.insertGraphAndFetch(personGraph);

280

281

const updated = await Person.query(trx)

282

.upsertGraphAndFetch(updateGraph);

283

284

// If any operation fails, all will be rolled back

285

});

286

```

287

288

### Error Handling

289

290

Graph operations can throw various errors for constraint violations.

291

292

**Usage Examples:**

293

294

```javascript

295

const { ValidationError, DBError } = require('objection');

296

297

try {

298

await Person.query().insertGraph(invalidGraph);

299

} catch (error) {

300

if (error instanceof ValidationError) {

301

console.log('Validation failed:', error.data);

302

} else if (error instanceof DBError) {

303

console.log('Database constraint violation:', error.message);

304

}

305

}

306

```

307

308

## Types

309

310

```typescript { .api }

311

interface InsertGraphOptions {

312

relate?: boolean | string[];

313

allowRefs?: boolean;

314

}

315

316

interface UpsertGraphOptions {

317

relate?: boolean | string[];

318

unrelate?: boolean | string[];

319

insertMissing?: boolean | string[];

320

update?: boolean | string[];

321

noInsert?: boolean | string[];

322

noUpdate?: boolean | string[];

323

noDelete?: boolean | string[];

324

noRelate?: boolean | string[];

325

noUnrelate?: boolean | string[];

326

allowRefs?: boolean;

327

}

328

329

interface GraphParameters {

330

'#dbRef'?: any;

331

'#ref'?: string;

332

'#id'?: string;

333

}

334

335

type PartialModelGraph<M> = Partial<M> & GraphParameters & {

336

[K in keyof M]?: M[K] extends Model

337

? PartialModelGraph<M[K]>

338

: M[K] extends Array<infer U>

339

? U extends Model

340

? PartialModelGraph<U>[]

341

: M[K]

342

: M[K];

343

};

344

```