or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-operations.mdclient-operations.mdcontainer-operations.mddatabase-operations.mdindex.mdscript-operations.mduser-management.md

script-operations.mddocs/

0

# Script Operations

1

2

Server-side script operations including stored procedures, triggers, and user-defined functions (UDFs). The ScriptsProxy enables execution of custom JavaScript code within the Azure Cosmos DB engine for advanced data processing and business logic.

3

4

## Capabilities

5

6

### Stored Procedures

7

8

Server-side procedures written in JavaScript that execute within the database engine with transactional guarantees.

9

10

```python { .api }

11

def create_stored_procedure(self, body: dict, **kwargs):

12

"""

13

Create a new stored procedure.

14

15

Parameters:

16

- body: Stored procedure definition with 'id' and 'body' (JavaScript code)

17

- session_token: Session token for consistency

18

19

Returns:

20

Stored procedure properties

21

22

Raises:

23

CosmosResourceExistsError: If stored procedure already exists

24

"""

25

26

def list_stored_procedures(self, max_item_count: int = None, **kwargs):

27

"""

28

List all stored procedures in the container.

29

30

Parameters:

31

- max_item_count: Maximum number of procedures to return

32

- session_token: Session token for consistency

33

34

Returns:

35

Iterable of stored procedure items

36

"""

37

38

def query_stored_procedures(self, query: str, parameters: list = None, max_item_count: int = None, **kwargs):

39

"""

40

Query stored procedures using SQL syntax.

41

42

Parameters:

43

- query: SQL query string

44

- parameters: Query parameters

45

- max_item_count: Maximum items per page

46

- session_token: Session token for consistency

47

48

Returns:

49

Iterable of query results

50

"""

51

52

def get_stored_procedure(self, sproc: str, **kwargs):

53

"""

54

Get stored procedure definition.

55

56

Parameters:

57

- sproc: Stored procedure ID

58

- session_token: Session token for consistency

59

60

Returns:

61

Stored procedure properties

62

63

Raises:

64

CosmosResourceNotFoundError: If stored procedure doesn't exist

65

"""

66

67

def replace_stored_procedure(self, sproc: str, body: dict, **kwargs):

68

"""

69

Replace stored procedure definition.

70

71

Parameters:

72

- sproc: Stored procedure ID

73

- body: Updated stored procedure definition

74

- session_token: Session token for consistency

75

- etag: ETag for conditional operations

76

- match_condition: Match condition for conditional operations

77

78

Returns:

79

Updated stored procedure properties

80

"""

81

82

def delete_stored_procedure(self, sproc: str, **kwargs):

83

"""

84

Delete a stored procedure.

85

86

Parameters:

87

- sproc: Stored procedure ID

88

- session_token: Session token for consistency

89

- etag: ETag for conditional operations

90

- match_condition: Match condition for conditional operations

91

92

Raises:

93

CosmosResourceNotFoundError: If stored procedure doesn't exist

94

"""

95

96

def execute_stored_procedure(self, sproc: str, partition_key: str = None, params: list = None, enable_script_logging: bool = None, **kwargs):

97

"""

98

Execute a stored procedure.

99

100

Parameters:

101

- sproc: Stored procedure ID

102

- partition_key: Partition key value for the execution context

103

- params: Parameters to pass to the stored procedure

104

- enable_script_logging: Enable console.log output in stored procedure

105

- session_token: Session token for consistency

106

107

Returns:

108

Stored procedure execution result

109

110

Raises:

111

CosmosHttpResponseError: If execution fails

112

"""

113

```

114

115

### Triggers

116

117

Pre-triggers and post-triggers that execute automatically before or after item operations.

118

119

```python { .api }

120

def create_trigger(self, body: dict, **kwargs):

121

"""

122

Create a new trigger.

123

124

Parameters:

125

- body: Trigger definition with 'id', 'body' (JavaScript), 'triggerType', 'triggerOperation'

126

- session_token: Session token for consistency

127

128

Returns:

129

Trigger properties

130

131

Raises:

132

CosmosResourceExistsError: If trigger already exists

133

"""

134

135

def list_triggers(self, max_item_count: int = None, **kwargs):

136

"""

137

List all triggers in the container.

138

139

Parameters:

140

- max_item_count: Maximum number of triggers to return

141

- session_token: Session token for consistency

142

143

Returns:

144

Iterable of trigger items

145

"""

146

147

def query_triggers(self, query: str, parameters: list = None, max_item_count: int = None, **kwargs):

148

"""

149

Query triggers using SQL syntax.

150

151

Parameters:

152

- query: SQL query string

153

- parameters: Query parameters

154

- max_item_count: Maximum items per page

155

- session_token: Session token for consistency

156

157

Returns:

158

Iterable of query results

159

"""

160

161

def get_trigger(self, trigger: str, **kwargs):

162

"""

163

Get trigger definition.

164

165

Parameters:

166

- trigger: Trigger ID

167

- session_token: Session token for consistency

168

169

Returns:

170

Trigger properties

171

172

Raises:

173

CosmosResourceNotFoundError: If trigger doesn't exist

174

"""

175

176

def replace_trigger(self, trigger: str, body: dict, **kwargs):

177

"""

178

Replace trigger definition.

179

180

Parameters:

181

- trigger: Trigger ID

182

- body: Updated trigger definition

183

- session_token: Session token for consistency

184

- etag: ETag for conditional operations

185

- match_condition: Match condition for conditional operations

186

187

Returns:

188

Updated trigger properties

189

"""

190

191

def delete_trigger(self, trigger: str, **kwargs):

192

"""

193

Delete a trigger.

194

195

Parameters:

196

- trigger: Trigger ID

197

- session_token: Session token for consistency

198

- etag: ETag for conditional operations

199

- match_condition: Match condition for conditional operations

200

201

Raises:

202

CosmosResourceNotFoundError: If trigger doesn't exist

203

"""

204

```

205

206

### User Defined Functions

207

208

Custom JavaScript functions that can be used in queries for complex calculations and data transformations.

209

210

```python { .api }

211

def create_user_defined_function(self, body: dict, **kwargs):

212

"""

213

Create a new user-defined function.

214

215

Parameters:

216

- body: UDF definition with 'id' and 'body' (JavaScript code)

217

- session_token: Session token for consistency

218

219

Returns:

220

UDF properties

221

222

Raises:

223

CosmosResourceExistsError: If UDF already exists

224

"""

225

226

def list_user_defined_functions(self, max_item_count: int = None, **kwargs):

227

"""

228

List all user-defined functions in the container.

229

230

Parameters:

231

- max_item_count: Maximum number of UDFs to return

232

- session_token: Session token for consistency

233

234

Returns:

235

Iterable of UDF items

236

"""

237

238

def query_user_defined_functions(self, query: str, parameters: list = None, max_item_count: int = None, **kwargs):

239

"""

240

Query user-defined functions using SQL syntax.

241

242

Parameters:

243

- query: SQL query string

244

- parameters: Query parameters

245

- max_item_count: Maximum items per page

246

- session_token: Session token for consistency

247

248

Returns:

249

Iterable of query results

250

"""

251

252

def get_user_defined_function(self, udf: str, **kwargs):

253

"""

254

Get user-defined function definition.

255

256

Parameters:

257

- udf: UDF ID

258

- session_token: Session token for consistency

259

260

Returns:

261

UDF properties

262

263

Raises:

264

CosmosResourceNotFoundError: If UDF doesn't exist

265

"""

266

267

def replace_user_defined_function(self, udf: str, body: dict, **kwargs):

268

"""

269

Replace user-defined function definition.

270

271

Parameters:

272

- udf: UDF ID

273

- body: Updated UDF definition

274

- session_token: Session token for consistency

275

- etag: ETag for conditional operations

276

- match_condition: Match condition for conditional operations

277

278

Returns:

279

Updated UDF properties

280

"""

281

282

def delete_user_defined_function(self, udf: str, **kwargs):

283

"""

284

Delete a user-defined function.

285

286

Parameters:

287

- udf: UDF ID

288

- session_token: Session token for consistency

289

- etag: ETag for conditional operations

290

- match_condition: Match condition for conditional operations

291

292

Raises:

293

CosmosResourceNotFoundError: If UDF doesn't exist

294

"""

295

```

296

297

## Usage Examples

298

299

### Stored Procedures

300

301

```python

302

# Get scripts proxy

303

scripts = container.scripts

304

305

# Create a stored procedure

306

sproc_definition = {

307

"id": "createItemsProc",

308

"body": """

309

function createItemsProc(items) {

310

var context = getContext();

311

var collection = context.getCollection();

312

var response = context.getResponse();

313

314

if (!items || items.length === 0) {

315

throw new Error('Items array is required');

316

}

317

318

var created = 0;

319

320

function createNextItem(index) {

321

if (index >= items.length) {

322

response.setBody({ created: created });

323

return;

324

}

325

326

var item = items[index];

327

var isAccepted = collection.createDocument(

328

collection.getSelfLink(),

329

item,

330

function(err, doc) {

331

if (err) throw err;

332

created++;

333

createNextItem(index + 1);

334

}

335

);

336

337

if (!isAccepted) {

338

response.setBody({ created: created, stopped: true });

339

}

340

}

341

342

createNextItem(0);

343

}

344

"""

345

}

346

347

# Create the stored procedure

348

scripts.create_stored_procedure(sproc_definition)

349

350

# Execute the stored procedure

351

items_to_create = [

352

{"id": "item1", "category": "Electronics", "name": "Phone"},

353

{"id": "item2", "category": "Electronics", "name": "Tablet"}

354

]

355

356

result = scripts.execute_stored_procedure(

357

sproc="createItemsProc",

358

partition_key="Electronics",

359

params=[items_to_create],

360

enable_script_logging=True

361

)

362

print(f"Created {result['created']} items")

363

364

# List stored procedures

365

procedures = list(scripts.list_stored_procedures())

366

for proc in procedures:

367

print(f"Stored Procedure: {proc['id']}")

368

```

369

370

### Triggers

371

372

```python

373

# Create a pre-trigger for validation

374

pre_trigger = {

375

"id": "validateItem",

376

"triggerType": "Pre",

377

"triggerOperation": "Create",

378

"body": """

379

function validateItem() {

380

var context = getContext();

381

var request = context.getRequest();

382

var body = request.getBody();

383

384

// Validate required fields

385

if (!body.name || body.name.length === 0) {

386

throw new Error('Item must have a name');

387

}

388

389

if (!body.category) {

390

throw new Error('Item must have a category');

391

}

392

393

// Auto-generate timestamp

394

body.createdAt = new Date().toISOString();

395

396

request.setBody(body);

397

}

398

"""

399

}

400

401

scripts.create_trigger(pre_trigger)

402

403

# Create a post-trigger for logging

404

post_trigger = {

405

"id": "logCreation",

406

"triggerType": "Post",

407

"triggerOperation": "Create",

408

"body": """

409

function logCreation() {

410

var context = getContext();

411

var response = context.getResponse();

412

var body = response.getBody();

413

414

console.log('Item created:', body.id);

415

}

416

"""

417

}

418

419

scripts.create_trigger(post_trigger)

420

421

# Create item with triggers

422

item = {"id": "triggered_item", "category": "Electronics"}

423

created_item = container.create_item(

424

body=item,

425

pre_trigger_include="validateItem",

426

post_trigger_include="logCreation"

427

)

428

```

429

430

### User Defined Functions

431

432

```python

433

# Create a UDF for tax calculation

434

udf_definition = {

435

"id": "calculateTax",

436

"body": """

437

function calculateTax(price, taxRate) {

438

if (typeof price !== 'number' || typeof taxRate !== 'number') {

439

return 0;

440

}

441

return price * taxRate;

442

}

443

"""

444

}

445

446

scripts.create_user_defined_function(udf_definition)

447

448

# Use UDF in a query

449

query = """

450

SELECT

451

c.id,

452

c.name,

453

c.price,

454

udf.calculateTax(c.price, 0.08) as tax,

455

(c.price + udf.calculateTax(c.price, 0.08)) as totalPrice

456

FROM c

457

WHERE c.category = 'Electronics'

458

"""

459

460

items = list(container.query_items(

461

query=query,

462

enable_cross_partition_query=True

463

))

464

465

for item in items:

466

print(f"{item['name']}: ${item['price']} + ${item['tax']} = ${item['totalPrice']}")

467

468

# List UDFs

469

udfs = list(scripts.list_user_defined_functions())

470

for udf in udfs:

471

print(f"UDF: {udf['id']}")

472

```

473

474

### Advanced Stored Procedure with Error Handling

475

476

```python

477

# Stored procedure for batch processing with rollback

478

batch_sproc = {

479

"id": "batchUpdateProc",

480

"body": """

481

function batchUpdateProc(updates) {

482

var context = getContext();

483

var collection = context.getCollection();

484

var response = context.getResponse();

485

486

var updated = 0;

487

var errors = [];

488

489

function updateNextItem(index) {

490

if (index >= updates.length) {

491

response.setBody({

492

updated: updated,

493

errors: errors

494

});

495

return;

496

}

497

498

var update = updates[index];

499

500

var isAccepted = collection.replaceDocument(

501

update.link,

502

update.item,

503

function(err, doc) {

504

if (err) {

505

errors.push({

506

index: index,

507

error: err.message

508

});

509

} else {

510

updated++;

511

}

512

updateNextItem(index + 1);

513

}

514

);

515

516

if (!isAccepted) {

517

response.setBody({

518

updated: updated,

519

stopped: true,

520

errors: errors

521

});

522

}

523

}

524

525

updateNextItem(0);

526

}

527

"""

528

}

529

530

scripts.create_stored_procedure(batch_sproc)

531

532

# Execute batch update

533

updates = [

534

{

535

"link": "dbs/MyDB/colls/MyContainer/docs/item1",

536

"item": {"id": "item1", "category": "Electronics", "price": 299.99}

537

},

538

{

539

"link": "dbs/MyDB/colls/MyContainer/docs/item2",

540

"item": {"id": "item2", "category": "Electronics", "price": 199.99}

541

}

542

]

543

544

result = scripts.execute_stored_procedure(

545

sproc="batchUpdateProc",

546

partition_key="Electronics",

547

params=[updates]

548

)

549

550

print(f"Updated: {result['updated']}, Errors: {len(result.get('errors', []))}")

551

```