Deta Base SDK

The Deta library is the easiest way to store and retrieve data from your Deta Base. Currently, we support JavaScript (Node + Browser), Python 3 and Go. Drop us a line if you want us to support your favorite language.

note

A "Deta Base" instance is a collection of data, not unlike a Key-Value store, a MongoDB collection or a PostgreSQL/MySQL table. It will grow with your app's needs.

info

We have an alpha version of the Python Base Async SDK. Check the documentation here.

Installing#


Using NPM:
npm install deta

Using Yarn:

yarn add deta
note

If you are using the Deta SDK within a Deta Micro, you must include deta in your dependencies file (package.json or requirements.txt) to install the latest sdk version.

Instantiating#

To start working with your Base, you need to import the Deta class and initialize it with a Project Key. Then instantiate a subclass called Base with a database name of your choosing.

Deta Bases are created for you automatically when you start using them.


const { Deta } = require('deta'); // import Deta
// Initialize with a Project Key
const deta = Deta('project key');
// This how to connect to or create a database.
const db = deta.Base('simple_db');
// You can create as many as you want without additional charges.
const books = deta.Base('books');
note

If you are using Deta Base within a Deta Micro, the Deta SDK comes pre-installed and a valid project key is pre-set in the Micro's environment. There is no need to install the SDK or pass a key in the initialization step.

const { Deta } = require('deta');
const deta = Deta();
note

If you are using the deta npm package of 0.0.6 or below, Deta is the single default export and should be imported as such.

const Deta = require('deta');
warning

Your project key is confidential and meant to be used by you. Anyone who has your project key can access your database. Please, do not share it or commit it in your code.

Using#

Deta's Base class offers the following methods to interact with your Deta Base:

put – Stores an item in the database. It will update an item if the key already exists.

insert – Stores an item in the database but raises an error if the key already exists. (2x slower than put).

get – Retrieves an item from the database by its key.

fetch – Retrieves multiple items from the database based on the provided (optional) filters.

delete – Deletes an item from the database.

update – Updates an item in the database.

Storing Numbers#

info

Base currently supports maximum 16 digit numbers (integers and floating points), please store larger numbers as a string.

Put#

put is the fastest way to store an item in the database.

If an item already exists under a given key, put will replace this item.

In the case you do not provide us with a key, we will auto generate a 12 char long string as a key.

async put(data, key=null)

Parameters#

  • data (required) – Accepts: object (serializable), string, number, boolean and array.
    • Description: The data to be stored.
  • key (optional) – Accepts: string and null
    • Description: the key (aka ID) to store the data under. Will be auto generated if not provided.

Code Example#

const Deta = require('deta');
const deta = Deta("project key");
const db = deta.Base("simple_db");
// you can store objects
db.put({name: "alex", age: 77}) // A key will be automatically generated
db.put({name: "alex", age: 77}, "one") // We will use "one" as a key
db.put({name: "alex", age: 77, key:"one"}) // The key could also be included in the object itself
// or store simple types:
db.put("hello, worlds")
db.put(7)
db.put("success", "smart_work") // "success" is the value and "smart_work" is the key.
db.put(["a", "b", "c"], "my_abc")

Returns#

put returns a promise which resolves to the item on a successful put, otherwise it throws an Error.

Get#

get retrieves an item from the database by it's key.


async get(key)

Parameters#

  • key (required) – Accepts: string
    • Description: the key of which item is to be retrieved.

Code Example#

const item = await db.get('one'); // retrieving item with key "one"

Returns#

If the record is found, the promise resolves to:

{
name: 'alex', age: 77, key: 'one'
}

If not found, the promise will resolve to null.

Delete#

delete deletes an item from the database that matches the key provided.


async delete(key)

Parameters#

  • key (required) – Accepts: string
    • Description: the key of which item is to be deleted.

Code Example#

const res = await db.delete("one")

Returns#

Always returns a promise which resolves to null, even if the key does not exist.

Insert#

The insert method inserts a single item into a Base, but is unique from put in that it will raise an error of the key already exists in the database.

insert is roughly 2x slower than put.


async insert(data, key=null)

Parameters#

  • data (required) – Accepts: object (serializable), string, number, boolean and array.
    • Description: The data to be stored.
  • key (optional) – Accepts: string and null
    • Description: the key (aka ID) to store the data under. Will be auto generated if not provided.

Code Example#

// will succeed, a key will be auto-generated
const res1 = await db.insert('hello, world');
// will succeed.
const res2 = await db.insert({message: 'hello, world'}, 'greeting1');
// will raise an error as key "greeting1" already existed.
const res3 = await db.insert({message: 'hello, there'}, 'greeting1');

Returns#

Returns a promise which resolves to the item on a successful insert, and throws an error if the key already exists.

Put Many#

The Put Many method puts up to 25 items into a Base at once on a single call.


async putMany(items)

Parameters#

  • items (required) – Accepts: Array of items, where each "item" can be an object (serializable), string, number, boolean or array.
    • Description: The list of items to be stored.

Code Example#

const res1 = await db.putMany([
{"name": "Beverly", "hometown": "Copernicus City", "key": "one"}, // key provided
"dude", // key auto-generated
["Namaskāra", "marhabaan", "hello", "yeoboseyo"] // key auto-generated
]);

Returns#

Returns a promise which resolves to the put items on a successful insert, and throws an error if you attempt to put more than 25 items.

{
"processed": {
"items": [
{
"hometown": "Copernicus City",
"key": "one",
"name": "Beverly"
},
{
"key": "jyesxxlrezo0",
"value": "dude"
},
{
"key": "5feqybn7lb05",
"value": [
"Namaskāra",
"hello",
"marhabaan",
"yeoboseyo"
]
}
]
}
}

Update#

update updates an existing item from the database.


async update(updates, key)

Parameters#

  • updates (required) - Accepts: object (JSON serializable)
    • Description: a json object describing the updates on the item
  • key (required) – Accepts: string
    • Description: the key of the item to be updated.

Note for storing numbers

Update operations#
  • Set : Set is practiced through normal key-value pairs. The operation changes the values of the attributes provided in the set object if the attribute already exists. If not, it adds the attribute to the item with the corresponding value.

  • Increment: Increment incrementes the value of an attribute. The attribute's value must be a number. The util base.util.increment(value) should be used to increment the value. The default value is 1 if not provided and it can also be negative.

  • Append: Append appends to a list. The util base.util.append(value) should be used to append the value. The value can be a primitive type or an array.

  • Prepend: Prepend prepends to a list. The util base.util.prepend(value) should be used to prepend the value. The value can be a primitive type or an array.

  • Trim: Trim removes an attribute from the item, the util base.util.trim() should be used as the value of an attribute.

Code Example#

Consider we have the following item in a base const users = deta.Base('users'):

{
"key": "user-a",
"username": "jimmy",
"profile": {
"age": 32,
"active": false,
"hometown": "pittsburgh"
},
"on_mobile": true,
"likes": ["anime"],
"purchases": 1
}

Then the following update operation :

const updates = {
"profile.age": 33, // set profile.age to 33
"profile.active": true, // set profile.active to true
"profile.email": "jimmy@deta.sh", // create a new attribute 'profile.email'
"profile.hometown": users.util.trim(), // remove 'profile.hometown'
"on_mobile": users.util.trim(), // remove 'on_mobile'
"purchases": users.util.increment(2), // increment 'purchases' by 2, default value is 1
"likes": users.util.append("ramen") // append 'ramen' to 'likes', also accepts an array
}
const res = await db.update(updates, "user-a");

Results in the following item in the base:

{
"key": "user-a",
"username": "jimmy",
"profile": {
"age": 33,
"active": true,
"email": "jimmy@deta.sh"
},
"likes": ["anime", "ramen"],
"purchases": 3
}

Returns#

If the item is updated, the promise resolves to null. Otherwise, an error is raised.

Fetch#

Fetch retrieves a list of items matching a query. It will retrieve everything if no query is provided.

A query is composed of a single query object or a list of queries.

In the case of a list, the indvidual queries are OR'ed.


async fetch(query, options)

Parameters#

  • query: is a single query object (dict) or list of queries. If omitted, you will get all the items in the database (up to 1mb).
  • options: optional params:
    • limit: the limit of the number of items you want to retreive, min value 1 if used.
    • last: the last key seen in a previous paginated response, provide this in a subsequent call to fetch further items.
note

Upto 1 MB of data is retrieved before filtering with the query. Thus, in some cases you might get an empty list of items but still the last key evaluated in the response.

To apply the query through all the items in your base, you have to call fetch until last is empty.

Returns#

A promise which resolves to an object with the following attributes:

  • count : The number of items in the response.

  • last: The last key seen in the fetch response. If last is not undefined further items are to be retreived.

  • items: The list of items retreived.

Example#

For the examples, let's assume we have a Base with the following data:

[
{
"key": "key-1",
"name": "Wesley",
"age": 27,
"hometown": "San Francisco",
},
{
"key": "key-2",
"name": "Beverly",
"age": 51,
"hometown": "Copernicus City",
},
{
"key": "key-3",
"name": "Kevin Garnett",
"age": 43,
"hometown": "Greenville",
}
]
const { items: myFirstSet } = await db.fetch({"age?lt": 30});
const { items: mySecondSet } = await db.fetch([
{ "age?gt": 50 },
{ "hometown": "Greenville" }
])

... will come back with following data:

myFirstSet:#
[
{
"key": "key-1",
"name": "Wesley",
"age": 27,
"hometown": "San Francisco",
}
]
mySecondSet:#
[
{
"key": "key-2",
"name": "Beverly",
"age": 51,
"hometown": "Copernicus City",
},
{
"key": "key-3",
"name": "Kevin Garnett",
"age": 43,
"hometown": "Greenville",
},
]

Fetch All Items#

let res = await db.fetch();
let allItems = res.items;
// continue fetching until last is not seen
while (res.last){
res = await db.fetch({}, {last: res.last});
allItems = allItems.concat(res.items);
}

Queries#

Queries are regular objects/dicts/maps with conventions for different operations.

Equal#
{"age": 22, "name": "Beverly"}
// hierarchical
{"user.profile.age": 22, "user.profile.name": "Beverly"}
{"fav_numbers": [2, 4, 8]}
{"time": {"day": "Tuesday", "hour": "08:00"}}
Not Equal#
{"user.profile.age?ne": 22}
Less Than#
{"user.profile.age?lt": 22}
Greater Than#
{"user.profile.age?gt": 22}
Less Than or Equal#
{"user.profile.age?lte": 22}
Greater Than or Equal#
{"user.profile.age?gte": 22}
Prefix#
{"user.id?pfx": "afdk"}

Range#

{"user.age?r": [22, 30]}

Contains#

{
// if user email contains the substring @deta.sh
"user.email?contains": "@deta.sh"
}
{
// if berlin is in a list of places lived
"user.places_lived_list?contains": "berlin"
}

Not Contains#

{
// if user email does not contain @deta.sh
"user.email?not_contains": "@deta.sh" // 'user.email?!contains' also valid
}
{
// if berlin is not in a list of places lived
"user.places_lived_list?not_contains": "berlin" // 'user.places_lived_list?!contains' also valid
}
note

?contains and ?not_contains only works for a list of strings if checking for membership in a list; it does not apply to list of other data types. You can store your lists always as a list of strings if you want to check for membership.

Contact#

hello@deta.sh