or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-queuing.mdconnection-pooling.mdconnectivity.mddata-types.mddatabase-objects.mdindex.mdlobs.mdpipeline.mdsoda.mdsql-execution.mdsubscriptions.md

soda.mddocs/

0

# Simple Oracle Document Access (SODA)

1

2

Simple Oracle Document Access (SODA) provides a NoSQL-style API for working with JSON documents in Oracle Database. SODA allows applications to create, read, update, and delete JSON documents stored in Oracle collections without writing SQL. The API provides document operations, filtering, indexing, and metadata management for JSON document storage.

3

4

## Capabilities

5

6

### SODA Database

7

8

The main entry point for SODA operations, accessible through a database connection.

9

10

```python { .api }

11

# Access SODA database through connection

12

def getSodaDatabase(self) -> SodaDatabase: ...

13

14

class SodaDatabase:

15

def createCollection(self, name: str, metadata: Union[str, dict] = None, mapMode: bool = False) -> SodaCollection:

16

"""

17

Creates a SODA collection with the given name and returns a new SODA

18

collection object. If you try to create a collection, and a collection

19

with the same name and metadata already exists, then that existing

20

collection is opened without error.

21

22

Parameters:

23

- name (str): Name of the collection to create

24

- metadata (Union[str, dict]): JSON metadata specifying collection configuration

25

- mapMode (bool): If True, map to existing table instead of creating new table

26

27

Returns:

28

SodaCollection: New or existing collection object

29

"""

30

31

def createDocument(self, content: Any, key: str = None, mediaType: str = "application/json") -> SodaDocument:

32

"""

33

Creates a SODA document usable for SODA write operations. You only need

34

to use this method if your collection requires client-assigned keys or

35

has non-JSON content.

36

37

Parameters:

38

- content (Any): Document content (dict, list, str, or bytes)

39

- key (str): Client-assigned key (if required by collection)

40

- mediaType (str): MIME type for non-JSON documents

41

42

Returns:

43

SodaDocument: New document object

44

"""

45

46

def getCollectionNames(self, startName: str = None, limit: int = 0) -> List[str]:

47

"""

48

Returns a list of the names of collections in the database that match

49

the criteria, in alphabetical order.

50

51

Parameters:

52

- startName (str): Starting collection name for filtering

53

- limit (int): Maximum number of names to return (0 for no limit)

54

55

Returns:

56

List[str]: Collection names in alphabetical order

57

"""

58

59

def openCollection(self, name: str) -> SodaCollection:

60

"""

61

Opens an existing collection with the given name and returns a new SODA

62

collection object. If a collection with that name does not exist, None

63

is returned.

64

65

Parameters:

66

- name (str): Name of the collection to open

67

68

Returns:

69

SodaCollection: Collection object or None if not found

70

"""

71

```

72

73

### SODA Collection

74

75

Represents a collection of JSON documents with methods for CRUD operations, indexing, and metadata access.

76

77

```python { .api }

78

class SodaCollection:

79

# Properties

80

name: str # Read-only collection name

81

metadata: dict # Read-only collection metadata

82

83

def createIndex(self, spec: Union[dict, str]) -> None:

84

"""

85

Creates an index on a SODA collection. The spec is expected to be a

86

dictionary or a JSON-encoded string.

87

88

Parameters:

89

- spec (Union[dict, str]): Index specification as dict or JSON string

90

"""

91

92

def drop(self) -> bool:

93

"""

94

Drops the collection from the database, if it exists. Note that if the

95

collection was created with mapMode set to True the underlying table

96

will not be dropped.

97

98

Returns:

99

bool: True if collection was dropped, False if it didn't exist

100

"""

101

102

def dropIndex(self, name: str, force: bool = False) -> bool:

103

"""

104

Drops the index with the specified name, if it exists.

105

106

Parameters:

107

- name (str): Name of the index to drop

108

- force (bool): Force dropping of spatial/search indexes

109

110

Returns:

111

bool: True if index was dropped, False if it didn't exist

112

"""

113

114

def find(self) -> SodaOperation:

115

"""

116

This method is used to begin an operation that will act upon documents

117

in the collection. It creates and returns a SodaOperation object which

118

is used to specify the criteria and the operation that will be

119

performed on the documents that match that criteria.

120

121

Returns:

122

SodaOperation: Operation builder for chaining criteria

123

"""

124

125

def getDataGuide(self) -> SodaDocument:

126

"""

127

Returns a SODA document object containing property names, data types

128

and lengths inferred from the JSON documents in the collection. It can

129

be useful for exploring the schema of a collection.

130

131

Returns:

132

SodaDocument: Data guide document or None if no documents exist

133

"""

134

135

def insertMany(self, docs: list) -> None:

136

"""

137

Inserts a list of documents into the collection at one time. Each of

138

the input documents can be a dictionary or list or an existing SODA

139

document object.

140

141

Parameters:

142

- docs (list): List of documents to insert

143

"""

144

145

def insertManyAndGet(self, docs: list, hint: str = None) -> list:

146

"""

147

Similarly to insertMany() this method inserts a list of documents into

148

the collection at one time. The only difference is that it returns a

149

list of SODA Document objects.

150

151

Parameters:

152

- docs (list): List of documents to insert

153

- hint (str): SQL hint for database processing

154

155

Returns:

156

list: List of inserted SodaDocument objects

157

"""

158

159

def insertOne(self, doc: Any) -> None:

160

"""

161

Inserts a given document into the collection. The input document can be

162

a dictionary or list or an existing SODA document object.

163

164

Parameters:

165

- doc (Any): Document to insert

166

"""

167

168

def insertOneAndGet(self, doc: Any, hint: str = None) -> SodaDocument:

169

"""

170

Similarly to insertOne() this method inserts a given document into the

171

collection. The only difference is that it returns a SODA Document

172

object.

173

174

Parameters:

175

- doc (Any): Document to insert

176

- hint (str): SQL hint for database processing

177

178

Returns:

179

SodaDocument: Inserted document object

180

"""

181

182

def listIndexes(self) -> list:

183

"""

184

Return a list of indexes associated with the collection.

185

186

Returns:

187

list: List of index specifications as dictionaries

188

"""

189

190

def save(self, doc: Any) -> None:

191

"""

192

Saves a document into the collection. This method is equivalent to

193

insertOne() except that if client-assigned keys are used, and the

194

document with the specified key already exists in the collection, it

195

will be replaced with the input document.

196

197

Parameters:

198

- doc (Any): Document to save

199

"""

200

201

def saveAndGet(self, doc: Any, hint: str = None) -> SodaDocument:

202

"""

203

Saves a document into the collection. This method is equivalent to

204

insertOneAndGet() except that if client-assigned keys are used, and the

205

document with the specified key already exists in the collection, it

206

will be replaced with the input document.

207

208

Parameters:

209

- doc (Any): Document to save

210

- hint (str): SQL hint for database processing

211

212

Returns:

213

SodaDocument: Saved document object

214

"""

215

216

def truncate(self) -> None:

217

"""

218

Removes all of the documents in the collection, similarly to what is

219

done for rows in a table by the TRUNCATE TABLE statement.

220

"""

221

```

222

223

### SODA Document

224

225

Represents a single JSON document with content, metadata, and access methods.

226

227

```python { .api }

228

class SodaDocument:

229

# Properties

230

createdOn: str # Read-only creation timestamp in ISO 8601 format

231

key: str # Read-only unique document key

232

lastModified: str # Read-only last modified timestamp in ISO 8601 format

233

mediaType: str # Read-only media type (usually "application/json")

234

version: str # Read-only document version

235

236

def getContent(self) -> Union[dict, list]:

237

"""

238

Returns the content of the document as a dictionary or list. This

239

method assumes that the content is application/json and will raise an

240

exception if this is not the case.

241

242

Returns:

243

Union[dict, list]: Parsed JSON content or None if no content

244

"""

245

246

def getContentAsBytes(self) -> bytes:

247

"""

248

Returns the content of the document as a bytes object. If there is no

249

content, however, None will be returned.

250

251

Returns:

252

bytes: Raw document content or None if no content

253

"""

254

255

def getContentAsString(self) -> str:

256

"""

257

Returns the content of the document as a string. If the document

258

encoding is not known, UTF-8 will be used.

259

260

Returns:

261

str: Document content as string or None if no content

262

"""

263

```

264

265

### SODA Document Cursor

266

267

Iterator for streaming access to large result sets of documents.

268

269

```python { .api }

270

class SodaDocCursor:

271

def __iter__(self) -> SodaDocCursor: ...

272

def __next__(self) -> SodaDocument: ...

273

274

def close(self) -> None:

275

"""

276

Close the cursor now, rather than whenever __del__ is called. The

277

cursor will be unusable from this point forward; an Error exception

278

will be raised if any operation is attempted with the cursor.

279

"""

280

```

281

282

### SODA Operation

283

284

Fluent interface for building complex queries and operations on documents.

285

286

```python { .api }

287

class SodaOperation:

288

def count(self) -> int:

289

"""

290

Returns a count of the number of documents in the collection that match

291

the criteria. If skip() or limit() were called on this object, an

292

exception is raised.

293

294

Returns:

295

int: Number of matching documents

296

"""

297

298

def fetchArraySize(self, value: int) -> SodaOperation:

299

"""

300

This is a tuning method to specify the number of documents that are

301

internally fetched in batches by calls to getCursor() and

302

getDocuments().

303

304

Parameters:

305

- value (int): Batch size (0 for default of 100)

306

307

Returns:

308

SodaOperation: Self for method chaining

309

"""

310

311

def filter(self, value: Union[dict, str]) -> SodaOperation:

312

"""

313

Sets a filter specification for complex document queries and ordering

314

of JSON documents. Filter specifications must be provided as a

315

dictionary or JSON-encoded string.

316

317

Parameters:

318

- value (Union[dict, str]): Filter specification

319

320

Returns:

321

SodaOperation: Self for method chaining

322

"""

323

324

def getCursor(self) -> SodaDocCursor:

325

"""

326

Returns a SodaDocCursor object that can be used to iterate over the

327

documents that match the criteria.

328

329

Returns:

330

SodaDocCursor: Cursor for iterating documents

331

"""

332

333

def getDocuments(self) -> list:

334

"""

335

Returns a list of SodaDocument objects that match the criteria.

336

337

Returns:

338

list: List of matching documents

339

"""

340

341

def getOne(self) -> Union[SodaDocument, None]:

342

"""

343

Returns a single SodaDocument object that matches the criteria. Note

344

that if multiple documents match the criteria only the first one is

345

returned.

346

347

Returns:

348

Union[SodaDocument, None]: First matching document or None

349

"""

350

351

def hint(self, value: str) -> SodaOperation:

352

"""

353

Specifies a hint that will be provided to the SODA operation when it is

354

performed. This is expected to be a string in the same format as SQL

355

hints but without any comment characters.

356

357

Parameters:

358

- value (str): SQL hint string

359

360

Returns:

361

SodaOperation: Self for method chaining

362

"""

363

364

def lock(self) -> SodaOperation:

365

"""

366

Specifies whether the documents fetched from the collection should be

367

locked (equivalent to SQL "select for update").

368

369

Returns:

370

SodaOperation: Self for method chaining

371

"""

372

373

def key(self, value: str) -> SodaOperation:

374

"""

375

Specifies that the document with the specified key should be returned.

376

This causes any previous calls made to this method and keys() to be

377

ignored.

378

379

Parameters:

380

- value (str): Document key to match

381

382

Returns:

383

SodaOperation: Self for method chaining

384

"""

385

386

def keys(self, value: list) -> SodaOperation:

387

"""

388

Specifies that documents that match the keys found in the supplied

389

sequence should be returned. This causes any previous calls made to

390

this method and key() to be ignored.

391

392

Parameters:

393

- value (list): List of document keys to match

394

395

Returns:

396

SodaOperation: Self for method chaining

397

"""

398

399

def limit(self, value: int) -> SodaOperation:

400

"""

401

Specifies that only the specified number of documents should be

402

returned. This method is only usable for read operations such as

403

getCursor() and getDocuments().

404

405

Parameters:

406

- value (int): Maximum number of documents to return

407

408

Returns:

409

SodaOperation: Self for method chaining

410

"""

411

412

def remove(self) -> int:

413

"""

414

Removes all of the documents in the collection that match the criteria.

415

The number of documents that have been removed is returned.

416

417

Returns:

418

int: Number of documents removed

419

"""

420

421

def replaceOne(self, doc: Any) -> bool:

422

"""

423

Replaces a single document in the collection with the specified

424

document. The input document can be a dictionary or list or an existing

425

SODA document object.

426

427

Parameters:

428

- doc (Any): Replacement document

429

430

Returns:

431

bool: True if a document was replaced, False otherwise

432

"""

433

434

def replaceOneAndGet(self, doc: Any) -> SodaDocument:

435

"""

436

Similarly to replaceOne(), this method replaces a single document in

437

the collection with the specified document. The only difference is that

438

it returns a SodaDocument object.

439

440

Parameters:

441

- doc (Any): Replacement document

442

443

Returns:

444

SodaDocument: Replaced document object

445

"""

446

447

def skip(self, value: int) -> SodaOperation:

448

"""

449

Specifies the number of documents that match the other criteria that

450

will be skipped. This method is only usable for read operations such as

451

getCursor() and getDocuments().

452

453

Parameters:

454

- value (int): Number of documents to skip

455

456

Returns:

457

SodaOperation: Self for method chaining

458

"""

459

460

def version(self, value: str) -> SodaOperation:

461

"""

462

Specifies that documents with the specified version should be returned.

463

Typically this is used with key() to implement optimistic locking.

464

465

Parameters:

466

- value (str): Document version to match

467

468

Returns:

469

SodaOperation: Self for method chaining

470

"""

471

```

472

473

## Usage Examples

474

475

```python

476

import oracledb

477

478

# Basic SODA usage

479

with oracledb.connect(user="user", password="pwd", dsn="localhost/orclpdb") as connection:

480

# Get SODA database

481

soda_db = connection.getSodaDatabase()

482

483

# Create or open a collection

484

collection = soda_db.createCollection("employees")

485

486

# Insert a document

487

doc_content = {"name": "John Doe", "department": "Engineering", "salary": 75000}

488

collection.insertOne(doc_content)

489

490

# Query documents

491

documents = collection.find().filter({"department": "Engineering"}).getDocuments()

492

for doc in documents:

493

print(f"Employee: {doc.getContent()}")

494

495

# Update a document

496

result = collection.find().key("some_key").replaceOne({"name": "Jane Doe", "department": "Marketing"})

497

498

# Remove documents

499

removed_count = collection.find().filter({"salary": {"$lt": 50000}}).remove()

500

print(f"Removed {removed_count} documents")

501

```