Skip to main content

Contributors Forks Stargazers Issues MIT License LinkedIn


Logo

Data Structure ORM

A single file ORM for SQLite in Python

Table of Contents

  1. About The Project
  2. Getting Started
  3. Usage
  4. Roadmap
  5. Contributing
  6. License
  7. Contact

About The Project

Data Structure ORM (dsORM) a tiny, extensible ORM that builds off of Python's built in data structures. dsORM can convert simple data structures such as dictionaries, enums, and dataclasses into tables. For fine control you can craft tables, columns, and constraints from simple base classes.

If SQLAlchemy's expression language comes to mind, yes, this is a bit like that. But dsORM is much simpler. The entire functional code is in a single file which is currently under 1,500 lines. For comparison, PeeWee, a fairly small ORM is 7,723 lines long in it's main file and that doesn't contain all functional code. SQLAlchemy as of this writing contains 343,975 lines of Python code (though admittedly it dwarfs dsORM's feature set.)

Designed for easy integration / modification

  • 100% Python
  • No external dependencies
  • 100% test coverage
  • Functional code in a single file

Should I use this?

You should not use dsORM if:

  • You can't work with SQLite
  • You want something that enforces best practices

You should use dsORM if:

  • You know SQL enough to get around and want to avoid some boilerplate
  • You are prototyping and want something minimal to stand in for another ORM
  • You want to make your own project tailored ORM and can use dsORM as a starting point
  • You cannot pip install in your environment and need a single file solution that can be bundled

Getting Started

To get a local copy up and running follow these simple steps.

Installing with pip

pip install dsorm

For information about cloning and dev setup see: Contributing

Usage

Here is an example showing basic usage.

import dataclasses
from enum import Enum

from dsorm import Comparison, Database, DataClassTable, make_table

# the .memory() constructor is equivilent to Database(db_path=":memory:", is_default=True)
db = Database.memory()


# Leverage enums for efficient small lookup tables
@make_table
class Team(Enum):
    UNASSIGNED = 0
    RED = 1
    BLUE = 2


@make_table
@dataclasses.dataclass
class Person(DataClassTable):
    first_name: str = None
    last_name: str = None
    team: Team = Team.UNASSIGNED


person = db.table("Person")

print(person.sql())
# CREATE TABLE IF NOT EXISTS person (id INTEGER PRIMARY KEY, first_name TEXT, last_name TEXT);


# Tables have insert, select, and delete methods which return subclasses of dsorm.Statement
stmt = person.insert(
    data=[
        {"first_name": "John", "last_name": "Doe", "team": Team.BLUE},
    ],
)

# Statements can be examined with .sql method
print(stmt.sql())
# INSERT INTO [Person] (first_name, last_name, team) VALUES ('John', 'Doe', 2)

# or executed with .execute()
stmt.execute()

# Subclasses of DataClassTable inherit a save method
Jane = Person(first_name="Jane", last_name="Doe", team=Team.RED).save()

# Select returns a list of dicts of rows matching the where
doe_family = person.select(
    where={"first_name": Comparison.like(target="J%n%")},
).execute()

print(doe_family)
# [
#     {'id': 1, 'first_name': 'John', 'last_name': 'Doe', 'team': <Team.BLUE: 2>
#     },
#     {'id': 2, 'first_name': 'Jane', 'last_name': 'Doe', 'team': <Team.RED: 1>
#     }
# ]

# And Delete
person.delete(where={"id": doe_family[0]["id"]}).execute()
print(person.select(column=["id", "first_name"]).execute())
# [{'id': '2', 'first_name': 'Jane'}]

The same example without comments

Further Examples

Roadmap

Needed features:

  • Subquery/CTE support
  • Grouping/Aggregates
  • Order/Limit/Offset

See the open issues for a list of proposed features (and known issues).

Contributing

Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are greatly appreciated.

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Add tests, we aim for 100% test coverage Using Coverage
  4. execute: py.test --cov-report xml:cov.xml --cov
  5. Commit your Changes (git commit -m 'Add some AmazingFeature')
  6. Push to the Branch (git push origin feature/AmazingFeature)
  7. Open a Pull Request

Cloning / Development setup

  1. Clone the repo and install
    git clone https://github.com/kajuberdut/dsorm.git
    cd dsorm
    pipenv install --dev
    
  2. Run tests
    pipenv shell
    py.test
    

For more about pipenv see: Pipenv Github

License

Distributed under the BSD Two-clause License. See LICENSE for more information.

Contact

Patrick Shechet - patrick.shechet@gmail.com

Project Link: https://github.com/kajuberdut/dsorm

Metadata

Release files for dsorm 0.0.8

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dsorm 0.0.8
File Size Uploaded Provenance
dsorm-0.0.8.tar.gz 23.1 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for dsorm 0.0.8
File Interpreter ABI Platform
dsorm-0.0.8-py3-none-any.whl Python 3 none any Details

Total release size: 39.2 kB

Release files / dsorm-0.0.8.tar.gz

Download URL dsorm-0.0.8.tar.gz
Size 23.1 kB
Tags Source
SHA-256 checksum
How to use checksums
bb6a5b87538af0d8ebaf603a9ae6958f8132ef6489706b888137f46688bd5f28
BLAKE2b-256 checksum
How to use checksums
ed70d09cec4145f1432ab76db93f7a9829925cd39f596ebbcc2501ab8781c34f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.4.1 importlib_metadata/3.10.0 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.60.0 CPython/3.8.3

Release files / dsorm-0.0.8-py3-none-any.whl

Download URL dsorm-0.0.8-py3-none-any.whl
Size 16.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
245daba958ee58a0400801d9938635a9663e3cca721628e9b3fd0589be41d250
BLAKE2b-256 checksum
How to use checksums
ff8048e662dc2edb68151718b9660dac744f24fc2d5cf6bd1bf9966ae4e56aad
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.4.1 importlib_metadata/3.10.0 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.60.0 CPython/3.8.3

Security for dsorm 0.0.8

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page