Python lightweight database wrapper for SQLite

Question:

Is there a lightweight database wrapper in Python that I can use for SQLite. I would like something like Django’s ORM, but that I can just point to a database file and it’ll make the required API for me (i.e handle all the CRUD).

Asked By: Puzzled79

||

Answers:

SQLAlchemy may be what you are looking for.

http://www.sqlalchemy.org/

Answered By: Alex

Yeah, SQLAlchemy is great, but there are also other options. One of them is Peewee.
Very lightweight and it may fits perfectly with what you are looking for.

https://github.com/coleifer/peewee

Answered By: Gabriel Jordão

Definitely peewee. I’ve tried sqlalchemy but it’s a mess and there is no magic.

Other ORMs are no more developed or not so good, like SQLobject, Elixir (layer on top of sqlalchemy), PonyORM.
Peewee is the best I’ve seen so far in the python community, and it’s the closer to the main ORMs for ruby or for php.

Peewee also have many gems, like this handful shortcut

Person.get_or_create(name='Foo', surname='Bar')

that automagically take the person named ‘Foo Bar’ from the DB if it exists, otherwise it creates it .

Answered By: Alessio

You can checkout RabaDB. It has arguably one of the simplest interfaces out there.

class Human(R.Raba) :
        _raba_namespace = 'test_namespace'

        #Everything that is not a raba object is primitive
        name = rf.Primitive()
        age = rf.Primitive()
        city = rf.Primitive()

        #Only Cars can fit into this relation
        cars = rf.Relation('Car')

        #best friend can only be a human
        bestFriend = rf.RabaObject('Human')

It is optimized to have little memory consumption, it supports queries by examples, inheritance, has debugging tools and even allows you to fall back onto SQL if needed.

Answered By: tariqdaouda

Just finished this very simple and cool python object oriented orm layer.

https://github.com/lxknvlk/python_orm_sqlite

Answered By: lxknvlk

Disclaimer : I have an affiliation with package, sql30, suggested here.

sql30 can be another potential option for lightweight CRUD operations on SQLITE database. It is a zero weight ORM, written using only native python constructs and has no dependency on any other module which makes it great option for platforms which have limited or lagging support of Python such as ESX .

For the use case, asked in question here, user can simply

  1. Create a Class object referring to database file

  2. Define table schema (based on the columns of table) using simple JSON.

and you are ready for any CRUD operations.

An example is shown below.

Say the database file is reviews.db and one of the table in it is reviews which has fields of individual reviews such as rid, header, rating and desc(iption). One can do the CRUD operations as below.

# reviews.py
from sql30 import db

class Reviews(db.Model):
    PKEY = 'rid'
    DB_SCHEMA = {
        'db_name': 'reviews.db',
        'tables': [
            {
                'name': 'reviews',
                'fields': {
                    'rid': 'uuid',
                    'header': 'text',
                    'rating': 'int',
                    'desc': 'text'
                    },
                'primary_key': 'rid'
            }]
        }
    VALIDATE_BEFORE_WRITE = True

One can do CRUD operations as below now.

>>> import os
>>> import reviews


# Create ORM layer object instance.
>>> db = reviews.Reviews()

# With this, we can create/write records to db as following.
>>> tbl = 'reviews' # select database table, you want to operate on.
>>> db.write(tbl, rid=1, header='good thing', rating=5)
>>> db.write(tbl, rid=2, header='bad thing', rating=1, desc='what a disgusting thing')

# We can then read back the records individually are as whole as shown below.

# To read all the records from a table, simply pass the table name.
>>> db.read(tbl)
[(1, 'good thing', 5, ''), (2, 'bad thing', 1, 'what a disgusting thing')]

# To read the records from table, simply pass on the condition as params.
>>> db.read(tbl, rid=1) # Get records from table WHERE rid=1
[(1, 'good thing', 5, '')]

# Get records from table WHERE rid=1 and rating=3. Note that, there is no
# restriction on the order in which condition needs to be provided. Only
# the param name should be one of the COLUMN(s) in table.
>>> db.read(tbl, rating=3, rid=1)
[]
>>> db.read(tbl, rating=5, rid=1)
[(1, 'good thing', 5, '')]

# If we try to add another record with same primary key, it will error out.
>>> db.write(tbl, rid=1, header='good thing', rating=5)
Traceback (most recent call last):
  ...
  ...
sqlite3.IntegrityError: UNIQUE constraint failed: reviews.rid

# Updating the record is also possible by providing condition for records and updated values.
>>> where = {'rid': 2}
>>> db.update(tbl, condition=where, header='average item', rating=2)
>>> db.read(tbl)
[(1, 'good thing', 5, ''), (2, 'average item', 2, 'what a disgusting thing')]

# Deleteing the records is possble with any level of filtering.
>>> db.remove(tbl, rid=1)
>>> db.read(tbl)
[(2, 'average item', 2, 'what a disgusting thing')]

# At this point, however, all of your records are being maintained by SQLITE in-memory.
# However, commit API can be used to persist them in the DB file.
>>> db.commit()

Parallel operations are allowed and handled well as long as DB connection is used within same thread, which is essentially sqlite module requirement. Example of this is here.

Answered By: ViFI
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.