Skip to main content

A lightweight and high-performance object-relational mapper for Python.

Project description

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="daniel@lionzrule.com",
    question="Favorite species?",
    answer="lion"
)
leila = User(
    name="Leila",
    pswd="lioness",
    email="leila@lionzrule.com",
    question="Favorite species?",
    answer="lioness"
)
james = User(
    name="James",
    pswd="cheetah",
    email="james@cheetahzrule.com",
    question="Favorite species?",
    answer="cheetah"
)
abby = User(
    name="Abby",
    pswd="cheetahess",
    email="abby@cheetahzrule.com",
    question="Favorite species?",
    answer="cheetah"
)
fiona = User(
    name="Fiona",
    pswd="fox",
    email="fiona@foxezrule.com",
    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()

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cheetah_orm-2.0.0b7-py3-none-any.whl (13.8 kB view details)

Uploaded Python 3

File details

Details for the file cheetah_orm-2.0.0b7-py3-none-any.whl.

File metadata

  • Download URL: cheetah_orm-2.0.0b7-py3-none-any.whl
  • Upload date:
  • Size: 13.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.4

File hashes

Hashes for cheetah_orm-2.0.0b7-py3-none-any.whl
Algorithm Hash digest
SHA256 eee0b2759a720b4d99452ef5436caad6e7f4271132febd6a9e298208dd665b9e
MD5 59b57a556155f0bf8c43c4a62d3b9dc3
BLAKE2b-256 658c94ec3f5865493a4d84e553b2fb6d1c745544b73a8729ea72931f7f2ce8db

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page