alabama

A small and simple python orm to connect with postgresql database.


Keywords
orm, postgresql, alabama
License
MIT
Install
pip install alabama==0.0.2

Documentation

Alabama

A small and simple python orm to connect with postgresql database.

Build Status Code Climate Coverage Status Code Health Current version at PyPI Downloads per month on PyPI

How to use

Alabama is still on a beta version. Any problems or bugs, please open an issue.

0. Install

pip install alabama

1. Create a model

Create a model that will represent a table in your database, just like that:

from alabama.models import BaseModel, StringProperty, IntegerProperty

class Person(BaseModel):
    name = StringProperty(80)  # 80 is the size of characters that can fill this column
    lastname = StringProperty(60)
    age = FloatProperty()

    def __init__(self, name=None, age=None, lastname=None):
        self.name = name
        self.age = Age
        ...

All models have two methods: to_json and to_instance. The first convert the model into a json object and the second one convert the json object passed as parameter to an Model object. Just like that:

p = Person(name='felipe', age=23)
print(p.to_json())
>>> {'name': 'felipe', 'age': 23}

person_as_json = {'name': 'john', 'age': 40}
model = Person.to_instance(person_as_json)
print(model)
>>> <__main__.Person object at 0x10ccfba10>

2. Create a connection with the database

Create a file called db.properties this way:

db.name=alabama
db.user=alabama
db.password=alabama
db.host=localhost
db.show_sql=False

Then, you'll start your connection with the postgresql database.

database = connection.start_db('../the/path/of_your_file/db.properties')
connection.create_pool(database)

And then... it's working! Alabama it's ready to use it.

3. Use the API

API Documentation

The hole thing in Alabama is the storage API. This module allows you to interact with your model and use then to interact with your database. Beyond the storage, Alabama also has the an API to handle with transactions. Check both here:

1. storage

from alabama import storage

create_database

This will create the table of all the models passed as parameter.

storage.create_database(Person)
storage.create_database([Person, Client, Item])

put

Put will call the insert method if the object doesn't have an id. If it does the update method will be called. The put method returns the same object with the id property.

john = Person(name='felipe', age=20)
john = storage.put(john) # now it has the id property
print john.id

insert

Insert method returns True or False. Obviously, True if the object was inserted in database; False if the opposite happened.

storage.insert(Person(name='jackson', age=20))

find

Get all Persons

storage.find(Person)

find where

Filter by fields and using limit

storage.find(Person, limit=1, where={'age': 20, 'name': 'jackson'})     

get_all

Find using more than one id. get_all method returns a list of that model.

uuids.append(storage.put(Person()).uuid)
uuids.append(storage.put(Person()).uuid)
uuids.append(storage.put(Person()).uuid)
uuids.append(storage.put(Person()).uuid)
persons = storage.get_all(Person, uuids)

find where using IN

storage.find(Person, where={'age': (Query.IN, [20, 21, 23])})

delete all

storage.delete(Person)

delete by id

storage.delete(Person, uuid=person_uuid)

update

To the update method, pass a json object that represents those fields will be updated.

person = Person(name='john', age=50)
person = storage.put(person)
storage.update(person, where={'age': 10, 'name': 'mouse'})

join

The storage.query returns a dict that the keys are the names of the classes that are beeing used in the Query operation. In the case bellow, the storage.query can return a dict with the keys 'Age' and 'Person'.

query = Query(Person, alias='p').select(['p.*'])\
              .join(Age, alias='a', on='p.name = a.name')\
              .where({'p.name': 'alabama'})\
              .order("p.lastname DESC")

results = storage.query(query)
print results['Person'][0].lastname

2. Model

1. to_json

Converts the model into a json object

p = Person(name='felipe', age=23)
print(p.to_json())
>>> {'name': 'felipe', 'age': 23}

2. to_instace

Converts the json object passed as parameter to an Model object. Just like that:

person_as_json = {'name': 'john', 'age': 40}
model = Person.to_instance(person_as_json)
print(model)
>>> <__main__.Person object at 0x10ccfba10>

3. columns

Returns the name of all columns of that model

class User(BaseModel):
  name = StringProperty()
  lastname = StringProperty()

print User.columns()
>>> ['lastname', 'name', 'uuid']
new_user = User()
print new_user.columns()
>>> ['lastname', 'name', 'uuid']

4. table_name

Returns the name of the table of that model

5. create_table_sql

Returns the sql that is used to create that table.

3. Properties

You can use these properties to represent your columns: StringProperty, IntegerProperty, FloatProperty, EnumProperty, BooleanProperty.

from models import StringProperty, IntegerProperty, FloatProperty, EnumProperty, BooleanProperty

StringProperty

You can pass an argument to StringProperty to set the size of that column. The default value is 512.

class UserModel(BaseModel):
    name = StringProperty(80)

4. Handling with Transactions

Alabama has the @transaction decorator that helps you to create a transaction in the database. When you use this decorator, a transaction in the database will be opened at the beginning of the method and will be closed at the end of your function. As you can see:

from alabama.connection import transaction

@transaction
def save_user():
    user = User(name='alabama', lastname='shakes')
    storage.put(user)

A good way to handle with transactions is using them in the entrypoint of your api. Let's see an example:

from alabama.connection import transaction

@transaction
@app.post('/user/')
def new_user():
    user = User.to_instance(self.request.json())
    storage.put(user)

If something bad happen when you're doing some operation at the database, Alabama will do a rollback and release an exception.

More documentantion

Do you want know more about Alabama? Take a look at the source code and the tests, it's easy to understand. The tests/test_api.py file it's where all the storage methods are tested, it's a good way to start.

Details

  • Alabama use uuid as id.
  • The "__init__" of all models must have only keyword arguments or no one at all.

Another ORM?

Yep. Let's a build a really simple one. An ORM with few documentation, not because we don't care about it, but 'cause it's really simple to use it.

Contributing

Development

You can use Docker:

$ docker build -t 'alabama' .
$ ./run_tests.sh

Alternativelly, you can install all the dependencies in your machine running the command:

$ ./install.sh

Please follow the pep8 rules (more details at .pep8 file).