# Database Viper provides two database types for persistence: | Type | Use Case | History | |------------------|--------------------------|-----------| | `Database` | Simple key-value storage | No | | `CommitDatabase` | Versioned data | Yes (DAG) | This page covers the simple `Database`. For versioned storage, see [CommitDatabase](commit.md). --- ## Creating a Database In-memory and on-disk variants: ```{doctest} >>> db = Database.create_in_memory() >>> db.in_memory() True ``` ```pycon >>> db = Database.create("data.vdb") >>> db = Database.create("data.vdb", documentation="Cache for processed meshes") >>> db = Database.open("data.vdb") >>> db = Database.open("data.vdb", readonly=True) ``` Before opening, you can check if a file is a valid Database: ```pycon >>> Database.is_compatible("data.vdb") True ``` --- ## Remote Access Database supports network access through a server: ```pycon >>> Database.databases("server.local") ['cache', 'index'] >>> db = Database.connect("cache", "server.local") >>> db = Database.connect_local("cache", "/tmp/project.sock") ``` See [Server](../tools/server.md) for deployment details. --- ## Setting Up Definitions ```{doctest} >>> _ = db.extend_definitions(_tuto_defs) >>> sorted(str(a).split()[-1] for a in db.definitions().attachments()) ['Tuto::account', 'Tuto::avatar', 'Tuto::identity', 'Tuto::login', 'Tuto::portrait'] ``` In your own code you would assemble definitions from your DSM model: ```pycon >>> builder = DSMBuilder.assemble("model.dsm") >>> report, dsm_defs, defs = builder.parse() >>> db.extend_definitions(defs) >>> defs.inject() ``` --- ## CRUD Operations Create a key and a document: ```{doctest} >>> key = TUTO_A_USER_LOGIN.create_key() >>> login = TUTO_A_USER_LOGIN.create_document() >>> login.nickname = "alice" ``` Write — all mutations require a transaction: ```{doctest} >>> db.begin_transaction() >>> _ = db.set(TUTO_A_USER_LOGIN, key, login) >>> db.commit() ``` Read: ```{doctest} >>> result = db.get(TUTO_A_USER_LOGIN, key) >>> result.unwrap() {nickname='alice', password=''} ``` Check existence: ```{doctest} >>> db.has(TUTO_A_USER_LOGIN, key) True ``` Update: ```{doctest} >>> db.begin_transaction() >>> login.password = "secret" >>> _ = db.set(TUTO_A_USER_LOGIN, key, login) >>> db.commit() >>> db.get(TUTO_A_USER_LOGIN, key).unwrap() {nickname='alice', password='secret'} ``` List keys for an attachment — `keys()` returns a `ValueSet` of `ValueUUId`: ```{doctest} >>> isinstance(db.keys(TUTO_A_USER_LOGIN), ValueSet) True >>> len(db.keys(TUTO_A_USER_LOGIN)) 1 ``` Delete: ```{doctest} >>> db.begin_transaction() >>> _ = db.delete(TUTO_A_USER_LOGIN, key) >>> db.commit() >>> db.has(TUTO_A_USER_LOGIN, key) False ``` --- ## Transactions All write operations require a transaction: ```{doctest} >>> db.begin_transaction() >>> db.in_transaction() True >>> db.commit() >>> db.in_transaction() False ``` A transaction can also be rolled back: ```{doctest} >>> db.begin_transaction() >>> _ = db.set(TUTO_A_USER_LOGIN, key, login) >>> db.rollback() >>> db.has(TUTO_A_USER_LOGIN, key) False ``` **Safe transaction pattern** — use try/finally to ensure cleanup: ```python db.begin_transaction() try: db.set(attachment, key, document) db.commit() except ViperError: db.rollback() raise ``` --- ## Lifecycle Always close a database when done, especially for on-disk databases: ```{doctest} >>> tmp_db = Database.create_in_memory() >>> tmp_db.close() >>> tmp_db.is_closed() True ``` --- ## Metadata `Database` exposes a few metadata accessors: ```{doctest} >>> db.in_memory() True >>> db.path() 'InMemory' >>> isinstance(db.uuid(), ValueUUId) True >>> db.codec_name() 'StreamBinary' ``` For an on-disk database, `path()` returns the file path and `documentation()` returns the string passed to `Database.create(..., documentation=...)`. --- ## Choosing Between Database and CommitDatabase | Feature | Database | CommitDatabase | |----------------------|----------------------|------------------| | Simple CRUD | ✓ | ✓ | | History | ✗ | ✓ | | Sync | ✗ | ✓ | | Embedded definitions | ✓ | ✓ | | Remote access | ✓ | ✓ | | Blob storage | ✓ | ✓ | --- ## What's Next - [CommitDatabase](commit.md) - Versioned database with history - [Blobs](blobs.md) - Binary data storage