Skip to content
This repository has been archived by the owner on Dec 29, 2024. It is now read-only.
/ Cheetah-ORM Public archive

A lightweight and high-performance object relational mappper written in pure Python.

License

Notifications You must be signed in to change notification settings

Cybermals/Cheetah-ORM

Repository files navigation

Cheetah-ORM

A lightweight and high-performance object relational mappper written in pure Python.

Installation

pip install cheetah_orm

Note: To use MySQL or MariaDB you will need to install the "pymysql" package as well. And to use PostgreSQL, you will need to install the "psycopg" package too. SQLite support requires no additonal packages.

Building

  1. clone this repo
  2. install the "wheel" package by executing pip install wheel
  3. from the repo folder, execute pip wheel .
  4. there will be a wheel file inside the "dist" folder

Features

  • support for sqlite3, MariaDB/MySQL, and PostgreSQL
  • high-level database-neutral API written in pure Python
  • automatically generates the needed SQL statements for whichever database system you prefer to use
  • rich filtering API supports any conditional statement that is supported by the underlying database system plus sorting, offsets, and limits
  • result set counting

Usage

#!/usr/bin/python3
"""Cheetah ORM - Demo"""

from datetime import datetime
import os
import unittest

from cheetah_orm.fields import (
    BigIntField,
    BlobField,
    DateTimeField,
    DoubleField,
    IntField,
    FloatField,
    PasswordField,
    StringField
)
from cheetah_orm.indexes import ForeignKey, Index, UniqueIndex
from cheetah_orm.mappers import SQLiteMapper
from cheetah_orm.model import DataModel


# Delete last database
try:
    os.unlink("users.db")

except:
    pass


# Define data models
class User(DataModel):
    table      = "users"
    name       = StringField(length=32, not_null=True)
    pswd       = PasswordField(length=128, not_null=True)
    email      = StringField(length=128, not_null=True)
    question   = StringField(length=128, not_null=True)
    answer     = StringField(length=128, not_null=True)
    joined     = DateTimeField(not_null=True, default="now()")
    ban        = DateTimeField(not_null=True, default="now()")
    name_idx   = UniqueIndex("name")
    email_idx  = UniqueIndex("email")
    joined_idx = Index("joined")


class Post(DataModel):
    table      = "posts"
    user       = BigIntField(not_null=True)
    date       = DateTimeField(not_null=True, default="now()")
    content    = StringField(length=65535, not_null=True)
    user_idx   = ForeignKey(User, "id")
    date_idx   = Index("date")


# Establish a database connection
mapper = SQLiteMapper()
mapper.connect(database="users.db")

# Initialize data models
mapper.init_model(User)
mapper.init_model(Post)

# Create some data models and save them
daniel = User(
    name="Daniel",
    pswd="lion",
    email="[email protected]",
    question="Favorite species?",
    answer="lion"
)
leila = User(
    name="Leila",
    pswd="lioness",
    email="[email protected]",
    question="Favorite species?",
    answer="lioness"
)
james = User(
    name="James",
    pswd="cheetah",
    email="[email protected]",
    question="Favorite species?",
    answer="cheetah"
)
abby = User(
    name="Abby",
    pswd="cheetahess",
    email="[email protected]",
    question="Favorite species?",
    answer="cheetah"
)
fiona = User(
    name="Fiona",
    pswd="fox",
    email="[email protected]",
    question="Favorite species?",
    answer="fox"
)
unknown = User(
    name="Unknown",
    pswd="",
    email="",
    question="",
    answer=""
)

mapper.save_model(daniel)
mapper.save_model(leila)
mapper.save_model(james)
mapper.save_model(abby)
mapper.save_model(fiona)
mapper.save_model(unknown)
mapper.commit()

# Update the models and save them
daniel.question = "Favorite animal?"
leila.question = "Favorite animal?"
james.question = "Favorite animal?"
abby.question = "Favorite animal?"
fiona.question = "Favorite animal?"

mapper.save_model(daniel)
mapper.save_model(leila)
mapper.save_model(james)
mapper.save_model(abby)
mapper.save_model(fiona)
mapper.commit()

# Delete a model
mapper.delete_model(User(id=6))
mapper.commit()

# Fetch all users
users = mapper.filter(User)
print("Users:")

for user in users:
    print(user)

print()

# Fetch Daniel
users = mapper.filter(User, "`name`=?", "Daniel")
print("Users Named 'Daniel':")

for user in users:
    print(user)

print()

# Fetch Leila and Abby
users = mapper.filter(User, "`name`=? OR `name`=?", "Leila", "Abby")
print("Users Named 'Leila' or 'Abby':")

for user in users:
    print(user)

print()

# Fetch all users with "Favorite animal?" as their security question ordered by username
users = mapper.filter(User, "`question`=?", "Favorite animal?", order_by=["name"])
print("Users with the Security Question 'Favorite animal?' Ordered by Username:")

for user in users:
    print(user)

print()

# The middle 2 users
users = mapper.filter(User, "`question`=?", "Favorite animal?", order_by=["name"], offset=1, limit=2)
print("The Middle 2 Users:")

for user in users:
    print(user)

print()

# Create some posts
post = Post(
    user=daniel.id,
    content="Hello everyone!"
)
mapper.save_model(post)

post = Post(
    user=leila.id,
    content="Hello!"
)
mapper.save_model(post)

post = Post(
    user=james.id,
    content="Hi!"
)
mapper.save_model(post)

post = Post(
    user=abby.id,
    content="Heya!"
)
mapper.save_model(post)

post = Post(
    user=fiona.id,
    content="Hello darling!"
)
mapper.save_model(post)

post = Post(
    user=fiona.id,
    content="Huh? ...Help!"
)
mapper.save_model(post)

post = Post(
    user=daniel.id,
    content="Oh no!"
)
mapper.save_model(post)

# Now delete a user
mapper.delete_model(fiona)
mapper.commit()

# Verify that the user's posts were deleted too
post_cnt = mapper.count(Post, "`user`=?", 5)
print(f"Fiona has {post_cnt} post(s).")

# Disconnect from the database
mapper.disconnect()

About

A lightweight and high-performance object relational mappper written in pure Python.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages