Quickstart

If you’ve read our History then you know about jrnl.

Let’s use jrnl to show how to use alkali.

Entry

from alkali import Model, fields, tznow, JSONStorage

class Entry(Model):
    class Meta:
        storage = JSONStorage

    date  = fields.DateTimeField(primary_key = True)
    title = fields.StringField()
    body  = fields.StringField()

Lets break this down a bit.

Model

class Entry(Model):

Inherit from alkali.model.Model to make a new model. A Model class the equivalent to a database table schema. A Model instance is the equivalent to a row in that table.

Meta

class Meta:
    storage = JSONStorage

A Meta class is optional but it is handy to specify behaviour of the given model. In this case we’re using JSONStorage to save this model. Note: my version of jrnl uses JournalStorage

Known Meta properties are:

  • storage: specify the storage class that reads/writes to persistent storage. This value overrides the database default.
  • filename: specify the actual file to read/write to. If omitted, the filename will default to <model name>.<storage.extension>. The Database can override this of course.

Fields

date  = fields.DateTimeField(primary_key = True)
title = fields.StringField()
body  = fields.StringField()

At the class level, define some variables of type alkali.fields.IField.

Feel free to make your own if the few that come with alkali are insufficient. It would not be hard to make more complicated fields like a BitmapField, all one would have to do is override alkali.fields.IField.dumps() and alkali.fields.IField.loads().

alkali ships with the following fields:

Fields can take a keyword primary_key. Unlike Django, alkali doesn’t automatically create an id field that is the primary key, you must specify your own. Not only that, you can specify multiple fields as primary_key to create a compound primary key.

Journal

The main parent object in alkali is the alkali.database.Database. You’ll probably want to encapsulate the Database in something, in jrnls case that would be the Journal class.

from alkali import Database

class Journal:
    def __init__(self, filename=None, save_on_exit=True):

        # set the filename in Meta so future Storage calls have a
        # file to work with
        Entry.Meta.filename = filename

        self._db = Database( models=[Entry], save_on_exit=save_on_exit )
        self._db.load()

Lets break this down a bit.

Database

self._db = Database(models=[Entry], save_on_exit=save_on_exit)
self._db.load()

Create a Database object. The only required parameter is models, a list of Model classes that comprise the database.

save_on_exit tells the database to save all its data when it goes out of scope. This means the developer doesn’t have to explicitly call alkali.database.Database.store().

Meta

Entry.Meta.filename = filename

You can set the Model.Meta.filename at definition time or set it later at runtime.

By Our Powers Combined

So lets make an entry and save it to the database.

from alkali import Database, tznow

db = Database(models=[Entry], save_on_exit=True)

e = Entry(date=tznow(), title="my first entry", body="alkali is pretty good")
e.save()    # adds model instance to Entry.objects

db.store()  # saved to ./Entry.json because those are the defaults

e = Entry.objects.get( title="my first entry" )
e.body = "alkali is the bestest"

# updated entry will be saved when database goes out of scope
# because save_on_exit is True