Quick tutorial

Every single part of code block will be full example, so you can copy & paste it to play with it

Note

If you are windows user, you should keep separate index codes from __main__ (see https://bitbucket.org/codernity/codernitydb/issue/12/error-in-tutorial-sample) because CodernityDB uses inspect module, which doesn’t work as expected on windows.

Insert / Save / Store

I want to store 100 objects in database
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#!/usr/bin/env python

from CodernityDB.database import Database


def main():
    db = Database('/tmp/tut1')
    db.create()

    for x in xrange(100):
        print db.insert(dict(x=x))

    for curr in db.all('id'):
        print curr

if __name__ == '__main__':
    main()

Status

  • Autogenerated _id field
  • Simple key-value

As you can see database usage is very easy. That was the simplest usage of CodernityDB.

Get / Query

What if I would query database for x values ?
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#!/usr/bin/env python

from CodernityDB.database import Database
from CodernityDB.hash_index import HashIndex


class WithXIndex(HashIndex):

    def __init__(self, *args, **kwargs):
        kwargs['key_format'] = 'I'
        super(WithXIndex, self).__init__(*args, **kwargs)

    def make_key_value(self, data):
        a_val = data.get("x")
        if a_val is not None:
            return a_val, None
        return None

    def make_key(self, key):
        return key


def main():
    db = Database('/tmp/tut2')
    db.create()
    x_ind = WithXIndex(db.path, 'x')
    db.add_index(x_ind)

    for x in xrange(100):
        db.insert(dict(x=x))

    for y in xrange(100):
        db.insert(dict(y=y))

    print db.get('x', 10, with_doc=True)


if __name__ == '__main__':
    main()

As you can see now we can get a record with given x value. And don’t worry X index will be not affected with y assignments in 33-35 line.

Now you can run

print db.count(db.all, 'id')
print db.count(db.all, 'x')

As you expected, it will print you 200 and then 100 because only 100 records have x value, so they were indexed in X index

Status

  • Possibility to query by x value.

Duplicates

What if I have duplicate key values ?
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/usr/bin/env python

from CodernityDB.database import Database
from CodernityDB.hash_index import HashIndex


class WithXIndex(HashIndex):

    def __init__(self, *args, **kwargs):
        kwargs['key_format'] = 'I'
        super(WithXIndex, self).__init__(*args, **kwargs)

    def make_key_value(self, data):
        a_val = data.get("x")
        if a_val is not None:
            return a_val, None
        return None

    def make_key(self, key):
        return key


def main():
    db = Database('/tmp/tut3')
    db.create()
    x_ind = WithXIndex(db.path, 'x')
    db.add_index(x_ind)

    for x in xrange(100):
        db.insert(dict(x=x))

    for x in xrange(100):
        db.insert(dict(x=x))

    for y in xrange(100):
        db.insert(dict(y=y))

    print db.get('x', 10, with_doc=True)
    for curr in db.get_many('x', 10, limit=-1, with_doc=True):
        print curr

if __name__ == '__main__':
    main()

As you can see database supports duplicate keys.

Warning

Using Hash index, you can’t rely on record order, using all() or get_many().

Ordered data

OK, but I would to have them in order from range?
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/usr/bin/env python

from CodernityDB.database import Database
from CodernityDB.tree_index import TreeBasedIndex


class WithXIndex(TreeBasedIndex):

    def __init__(self, *args, **kwargs):
        kwargs['node_capacity'] = 10
        kwargs['key_format'] = 'I'
        super(WithXIndex, self).__init__(*args, **kwargs)

    def make_key_value(self, data):
        t_val = data.get('x')
        if t_val is not None:
            return t_val, None
        return None

    def make_key(self, key):
        return key


def main():
    db = Database('/tmp/tut4')
    db.create()
    x_ind = WithXIndex(db.path, 'x')
    db.add_index(x_ind)

    for x in xrange(100):
        db.insert(dict(x=x))

    for y in xrange(100):
        db.insert(dict(y=y))

    print db.get('x', 10, with_doc=True)

    for curr in db.get_many('x', start=15, end=25, limit=-1, with_doc=True):
        print curr


if __name__ == '__main__':
    main()

Status

  • Possibility to get ordered values from given range

As you can see, it’s not that hard. Just change the base from HashIndex to TreeBasedIndex.

Update / Delete

OK, cool, what about updates ?

Update is very easy, let’s say you want to update all documents that have x % 5 == 0 and delete those with x % 7 == 0.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#!/usr/bin/env python

from CodernityDB.database import Database
from CodernityDB.tree_index import TreeBasedIndex


class WithXIndex(TreeBasedIndex):

    def __init__(self, *args, **kwargs):
        kwargs['node_capacity'] = 10
        kwargs['key_format'] = 'I'
        super(WithXIndex, self).__init__(*args, **kwargs)

    def make_key_value(self, data):
        t_val = data.get('x')
        if t_val is not None:
            return t_val, None
        return None

    def make_key(self, key):
        return key


def main():
    db = Database('/tmp/tut_update')
    db.create()
    x_ind = WithXIndex(db.path, 'x')
    db.add_index(x_ind)

    # full examples so we had to add first the data
    # the same code as in previous step

    for x in xrange(100):
        db.insert(dict(x=x))

    for y in xrange(100):
        db.insert(dict(y=y))

    # end of insert part

    print db.count(db.all, 'x')

    for curr in db.all('x', with_doc=True):
        doc = curr['doc']
        if curr['key'] % 7 == 0:
            db.delete(doc)
        elif curr['key'] % 5 == 0:
            doc['updated'] = True
            db.update(doc)

    print db.count(db.all, 'x')

    for curr in db.all('x', with_doc=True):
        print curr

if __name__ == '__main__':
    main()

Isn’t it easy ?

Index functions

I would like to calculate some averages...

There are two ways to do it:

  • Outside Database
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#!/usr/bin/env python

from CodernityDB.database import Database
from CodernityDB.tree_index import TreeBasedIndex

import random


class WithXIndex(TreeBasedIndex):

    def __init__(self, *args, **kwargs):
        kwargs['node_capacity'] = 10
        kwargs['key_format'] = 'I'
        super(WithXIndex, self).__init__(*args, **kwargs)

    def make_key_value(self, data):
        t_val = data.get('x')
        if t_val is not None:
            return t_val, None
        return None

    def make_key(self, key):
        return key


def main():
    db = Database('/tmp/tut5_1')
    db.create()
    x_ind = WithXIndex(db.path, 'x')
    db.add_index(x_ind)

    for x in xrange(100):
        db.insert(dict(x=x, t=random.random()))

    l = []
    for curr in db.get_many('x', start=10, end=30, limit=-1, with_doc=True):
        l.append(curr['doc']['t'])
    print sum(l) / len(l)


if __name__ == '__main__':
    main()
  • Inside Database
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#!/usr/bin/env python

from CodernityDB.database import Database
from CodernityDB.tree_index import TreeBasedIndex

import random


class WithXIndex(TreeBasedIndex):

    def __init__(self, *args, **kwargs):
        kwargs['node_capacity'] = 10
        kwargs['key_format'] = 'I'
        super(WithXIndex, self).__init__(*args, **kwargs)

    def make_key_value(self, data):
        t_val = data.get('x')
        if t_val is not None:
            return t_val, None
            return None

    def make_key(self, key):
        return key

    def run_avg(self, db_obj, start, end):
        l = []
        gen = db_obj.get_many(
            'x', start=start, end=end, limit=-1, with_doc=True)
        for curr in gen:
            l.append(curr['doc']['t'])
        return sum(l) / len(l)


def main():
    db = Database('/tmp/tut5_2')
    db.create()
    x_ind = WithXIndex(db.path, 'x')
    db.add_index(x_ind)

    for x in xrange(100):
        db.insert(dict(x=x, t=random.random()))

    print db.run('x', 'avg', start=10, end=30)

if __name__ == '__main__':
    main()

Using that function inside database will perform much better when you will use CodernityDB-HTTP because then calculations will be done server side. It will also allow you to reuse the same logic code in different places.

In that examples we assumed that t value is not stored in our X index.

Note

If you’re CodernityDB-HTTP with CodernityDB-PyClient you should just change Database initialization (set host & port).

Tables, collections...?

OK, I got it, but can I store more than one data type in Database. Is there something like table or collection ?

Please refer to Tables, collections...? for this task.