lighty.db Package (Lighty framework ORM layer)

This is simple Python ORM that can be used now just with MongoDB. But I think in nearest future it would also support another backends. It looks almost like Django’s ORM but has a few differences.

Data model definition

To work with data at first you must to define a model class that represents database entity structure. For this purpose you can use lighty.db.models.Model class and Field’s subclasses from lighty.db.fields package. As example we create simple User entity with name, password and age:

from lighty.db import fields, models

class User(models.Model):
    name = fields.CharField()
    pass = fields.EmailField()
    age = fields.IntegerField()

    def __str__(self):
        return "%s %d" % (self.name, self.age)

This class can be easy mapped from database and into database. As example to store the data we need just::

User(name='Peter', pass='secret_phrase', age=18).put()

or for step by step properties setting:

john = User()
john.name = 'John'
john.age = 19
john.pass = 'remomber me'
john.save()

save() method is just an alias for put().

To get single entity from database by you can use get() method with name of the fields and their values to identify the record::

fred = User.get(name='fred', age=17)

To delete the entity from database you can use delete() method:

fred.delete()

Selecting the data from database

As you can see from previous examples, there is no managers for data accessing. For selection few records from database you can use queries to describe your requirements to items be selected. To get all the users from database you can use all() method of lighty.db.models.Model:

for user in User.all():
    print user

To delete all the users from database you can use delete() method from Query:

User.all().delete()

But let’s back to queries. To make a query it’s easy to use pure Python syntax. There is not suffixes for name arguments like it was in Django. You just need to use model’s fields and python operators to make a queries.:

User.all().where(User.age > 17)

selects all the users with age higher than 17. Or more complex example:

User.all().where((User.age > 17) & (User.name == 'Peter'))

selects all the users with age higher that 17 and name equals to ‘Peter’. For now you can use:

  • >, >=, <, <=, ==, &, | and + operators for all the values
  • +, -, /, * and ** operators for mathematical fields
  • slices for sequence fields (like a strings)

Also queries supports ordering:

User.all().order_by(User.age)

and slicing:

User.all()[0:10] # Select first 10 user

You can also make operations with queries:

query = User.all().where(User.age > 17) & User.all().where(User.age <= 20)

with results equivalent to:

query = User.all().where((User.age > 17) & (User.age <= 20))

All the queries are lazy and it would be just one request to database when you would like to fetch the data from database or iterate over query:

User.all().where((User.age > 17) & (User.age <= 20)).fetch()

But do not forget - now there is no caching for query results and multiply fetching or iterations requires multiply requests to database. If you would like to add caching you can use fetch method with argument cache set to True:

User.all().where((User.age > 17) & (User.age <= 20)).fetch(cache=True)

After that all other iterations over this query or len() function will work with cache. But cacheng uses additional memory and may work with outdated data.

Also you can update data for query:

User.all().where(User.age < 18).update(age=18)

models Module

class lighty.db.models.Model(key_name=None, is_new=True, **kwds)[source]

Bases: lighty.db.models.NewBase

Model is the superclass of all object entities in the datastore.

The programming model is to declare Python subclasses of the Model class, declaring datastore properties as class members of that class. So if you want to publish a story with title, body, and created date, you would do it like this:

class Story(db.Model):
title = db.CharField(max_length=255) body = db.TextField() created = db.DateTimeField(auto_now_add=True)
classmethod all(**kwds)[source]

Returns a query over all instances of this model from the datastore.

Returns:
Query that will retrieve all instances from entity collection.
delete()[source]

Deletes this entity from the datastore

classmethod entity_name()[source]

Get the table name

classmethod fields()[source]

Get fields list

classmethod get(**keys)[source]

Fetch instance from the datastore of a specific Model type using key.

We support Key objects and string keys (we convert them to Key objects automatically).

Useful for ensuring that specific instance types are retrieved from the datastore. It also helps that the source code clearly indicates what kind of object is being retreived. Example:

story = Story.get(story_key)
Args:
keys: Key within datastore entity collection to find; or string key; or list of Keys or string keys.
Returns:
a Model instance associated with key for provided class if it exists in the datastore, otherwise NoneMonad;
key()[source]

Unique key for this entity.

This property is only available if this entity is already stored in the datastore or if it has a full key, so it is available if this entity was fetched returned from a query, or after put() is called the first time for new entities, or if a complete key was given when constructed.

Returns:
Datastore key of persisted entity.
Raises:
AttributeError when entity is not persistent.
classmethod properties()[source]

Alias for fields.

put()[source]

Writes this model instance to the datastore.

If this instance is new, we add an entity to the datastore. Otherwise, we update this instance, and the key will remain the same.

Returns:
The key of the instance (either the existing key or a new key).
save()

Writes this model instance to the datastore.

If this instance is new, we add an entity to the datastore. Otherwise, we update this instance, and the key will remain the same.

Returns:
The key of the instance (either the existing key or a new key).
class lighty.db.models.ModelBase[source]

Bases: type

Metaclass used to ORM class generation from definitions

lighty.db.models.get_attr_source(name, cls)[source]

Helper method used to get the class where atribute was defined first

query Module

class lighty.db.query.Query(operand=None, operation=<built-in function __and__>, from_query=None, offset=0, limit=None, model=None)[source]

Bases: object

Query class

distinct()[source]

Return’s a query copy with distinct modifier

exclude(operand)

Creates new query from this query with operation AND and specified operand:

Query(ModelClass.field > 10) & Query(ModelClass.field < 20)

equivalent to:

SELECT * FROM modelclass WHERE field > 10 AND field < 20
fetch(cache=False)[source]

Fetch the result

filter(operand)

Creates new query from this query with operation AND and specified operand:

>>> Query(ModelClass.field > 10) & Query(ModelClass.field < 20)
SELECT * FROM modelclass WHERE field > 10 AND field < 20
include(operand)

Creates new query from this query with operation OR and specified operand

order_by(*args)[source]

Query ordering

values(fields)[source]

Return’s dictionary of fields for specified model

where(operand)

Creates new query from this query with operation AND and specified operand:

>>> Query(ModelClass.field > 10) & Query(ModelClass.field < 20)
SELECT * FROM modelclass WHERE field > 10 AND field < 20

fields Module

All fields described

class lighty.db.fields.AutoField(verbose_name=None, primary_key=False, db_index=False, unique=False, blank=False, null=False, choices=None, default=None, editable=True, error_messages={}, validators=(), help_text='', db_column=None, db_tablespace=False, unique_for_date=False, unique_for_month=False, unique_for_year=False)[source]

Bases: lighty.db.fields.IntegerField

An IntegerField that automatically increments according to available IDs. You usually won’t need to use this directly; a primary key field will automatically be added to your model if you don’t specify otherwise. See Automatic primary key fields.

class lighty.db.fields.BooleanField(verbose_name=None, primary_key=False, db_index=False, unique=False, blank=False, null=False, choices=None, default=None, editable=True, error_messages={}, validators=(), help_text='', db_column=None, db_tablespace=False, unique_for_date=False, unique_for_month=False, unique_for_year=False)[source]

Bases: lighty.db.fields.Field

A true/false field

The admin represents this as a checkbox

class lighty.db.fields.CharField(max_length=None, **options)[source]

Bases: lighty.db.fields.Field, lighty.db.functor.SequenceField

A string field, for small- to large-sized strings.

For large amounts of text, use TextField.

The admin represents this as an <input type=”text”> (a single-line input).

class lighty.db.fields.DateField(auto_now=False, auto_now_add=False, **options)[source]

Bases: lighty.db.fields.Field, lighty.db.functor.NumericField

A date, represented in Python by a datetime.date instance.

class lighty.db.fields.DateTimeField(auto_now=False, auto_now_add=False, **options)[source]

Bases: lighty.db.fields.DateField, lighty.db.functor.NumericField

A date and time, represented in Python by a datetime.datetime instance. Takes the same extra arguments as DateField.

get_value_for_datastore(model)[source]

Prepare value to store it into datastore.

Returns:
string represents field value in format “%Y-%m-%d %H:%M:%S”
make_value_from_datastore(value)[source]

Create date from value taken from datastore

Returns:
parsed DateTime object
class lighty.db.fields.DecimalField(max_digits=None, decimal_places=None, **options)[source]

Bases: lighty.db.fields.Field, lighty.db.functor.NumericField

A fixed-precision decimal number, represented in Python by a Decimal instance.

The admin represents this as an <input type=”text”> (a single-line input).

class lighty.db.fields.EmailField(max_length=75, **options)[source]

Bases: lighty.db.fields.CharField

A CharField that checks that the value is a valid e-mail address.

class lighty.db.fields.Field(verbose_name=None, primary_key=False, db_index=False, unique=False, blank=False, null=False, choices=None, default=None, editable=True, error_messages={}, validators=(), help_text='', db_column=None, db_tablespace=False, unique_for_date=False, unique_for_month=False, unique_for_year=False)[source]

Bases: lighty.db.functor.BaseField

Base field class. Declares basic methods an fields for all the field classes and fields

blank = False

is field can be empty on model saving

choices = None

list of values available for this field

db_column = None

name of the field inside database

db_index = False

is field a part of database index

db_tablespace = False

can be used to set additional datastorage parameter

default = None

default field value

editable = False

check is field value can be changed

error_messages = {}

error messages for validations

get_value_for_datastore(model)[source]

Get value prepared for saving in datastore

Args:
model: model instance to take value from
help_text = None

field detailed description

make_value_from_datastore(value)[source]

Create object from value was taken from datastore

model = None

Model contains field

name = None

Field name

null = False

is field can be None on model saving

primary_key = False

is field would be a primary key

unique = False

add checking for unique value

unique_for_date = False

check is field value unique for some date

unique_for_month = False

check is field value unique for month

unique_for_year = False

check if field value unique for year

validators = ()

list of the validators used to check field value before store it into the datastore

verbose_name = None

human readable field name

class lighty.db.fields.FloatField(verbose_name=None, primary_key=False, db_index=False, unique=False, blank=False, null=False, choices=None, default=None, editable=True, error_messages={}, validators=(), help_text='', db_column=None, db_tablespace=False, unique_for_date=False, unique_for_month=False, unique_for_year=False)[source]

Bases: lighty.db.fields.Field, lighty.db.functor.NumericField

A floating-point number represented in Python by a float instance.

The admin represents this as an <input type=”text”> (a single-line input).

class lighty.db.fields.ForeignKey(model, **kwargs)[source]

Bases: lighty.db.fields.Field

An object field can contains

get_value_for_datastore(model)[source]

Get object’s key

make_value_from_datastore(value)[source]

Get object for key

class lighty.db.fields.IPAddressField(**options)[source]

Bases: lighty.db.fields.Field

An IP address, in string format (e.g. “192.0.2.30”).

The admin represents this as an <input type=”text”> (a single-line input).

class lighty.db.fields.IntegerField(verbose_name=None, primary_key=False, db_index=False, unique=False, blank=False, null=False, choices=None, default=None, editable=True, error_messages={}, validators=(), help_text='', db_column=None, db_tablespace=False, unique_for_date=False, unique_for_month=False, unique_for_year=False)[source]

Bases: lighty.db.fields.Field, lighty.db.functor.NumericField

An integer. The admin represents this as an <input type=”text”> (a single-line input).

class lighty.db.fields.NullBooleanField(**options)[source]

Bases: lighty.db.fields.BooleanField

Like a BooleanField, but allows NULL as one of the options. Use this instead of a BooleanField with null=True. The admin represents this as a <select> box with “Unknown”, “Yes” and “No” choices.

class lighty.db.fields.PositiveIntegerField(**options)[source]

Bases: lighty.db.fields.IntegerField

Like an IntegerField, but must be positive.

class lighty.db.fields.SlugField(max_length=50, **options)[source]

Bases: lighty.db.fields.CharField

Slug is a newspaper term. A slug is a short label for something, containing only letters, numbers, underscores or hyphens. They’re generally used in URLs.

Implies setting Field.db_index to True.

It is often useful to automatically prepopulate a SlugField based on the value of some other value. You can do this automatically in the admin using prepopulated_fields.

class lighty.db.fields.TextField(verbose_name=None, primary_key=False, db_index=False, unique=False, blank=False, null=False, choices=None, default=None, editable=True, error_messages={}, validators=(), help_text='', db_column=None, db_tablespace=False, unique_for_date=False, unique_for_month=False, unique_for_year=False)[source]

Bases: lighty.db.fields.Field, lighty.db.functor.SequenceField

A large text field. The admin represents this as a <textarea> (a multi-line input).

class lighty.db.fields.TimeField(auto_now=False, auto_now_add=False, **options)[source]

Bases: lighty.db.fields.DateField, lighty.db.functor.NumericField

A time, represented in Python by a datetime.time instance. Accepts the same auto-population options as DateField.

get_value_for_datastore(model)[source]

Prepare value to store it into datastore.

Returns:
string represents field value in format “%Y-%m-%d %H:%M:%S”
make_value_from_datastore(value)[source]

Create date from value taken from datastore

Returns:
parsed Time object
class lighty.db.fields.URLField(verify_exists=True, max_length=200, **options)[source]

Bases: lighty.db.fields.CharField

A CharField for a URL.

The admin represents this as an <input type=”text”> (a single-line input).

lighty.db.fields.add_validator(validator, options)[source]

Helper function for adding validator into the validator’s list inside options dictionary. Written to make some field types constructor shorter.

backend Module

Define class for getting and storing data

class lighty.db.backend.Datastore(name, db_name)[source]

Bases: object

Class used to get and put data into database

get(model, **kwargs)[source]

Get item using number of arguments

put(model, item)[source]

Put item into datastore

functor Module

Make functor representation that helps to make queries and another lazy evaluations

class lighty.db.functor.BaseField[source]

Bases: lighty.functor.BaseFunctor

Base field class

class lighty.db.functor.FieldFunctor(parent, operator, operand)[source]

Bases: lighty.db.functor.BaseField

Class used to keep operations history

class lighty.db.functor.NumericField[source]

Bases: lighty.db.functor.BaseField

Base class for any numerical fields. It can be used to create:

integers floats decimals

class lighty.db.functor.SequenceField[source]

Bases: lighty.db.functor.BaseField

Class used for sequences fields creations. It can be used to create:

strings arrays dictionaries