Skip to main content

Cute sqlite3 wrapper for sql tables

Project description

Sql-Engine

My Sql-Engine is a cute little wrapper for sqlite3 table manipulations without any third party dependencies.

Features

Abstracts SQL queries into tiny little methods like, insert, insert_many, upsert, and not so little and tiny query builders a-la select, delete, update, etc. Sql-Engine also provides bulk insertion and transaction methods, like insert_many and select.fetchmany_iterator. Methods can be executed in transaction mode thanks to transaction context manager.

Sql-Engine implements Jupyter integration and dynamic schema building. You can easily instantiate existing database table and view it in cute little html representation.

from sqlengine import schema

table = schema.table_from_database("temp/chinook.db", "Invoice")
table
Invoice
InvoiceIdCustomerIdInvoiceDateBillingAddressBillingCityBillingStateBillingCountryBillingPostalCodeTotal
122021-01-01 00:00:00Theodor-Heuss-Straße 34StuttgartNoneGermany701741.98
242021-01-02 00:00:00Ullevålsveien 14OsloNoneNorway01713.96
382021-01-03 00:00:00Grétrystraat 63BrusselsNoneBelgium10005.94
4142021-01-06 00:00:008210 111 ST NWEdmontonABCanadaT6G 2C78.91
5232021-01-11 00:00:0069 Salem StreetBostonMAUSA211313.86
6372021-01-19 00:00:00Berger Straße 10FrankfurtNoneGermany603160.99
7382021-02-01 00:00:00Barbarossastraße 19BerlinNoneGermany107791.98
8402021-02-01 00:00:008, Rue HanovreParisNoneFrance750021.98
9422021-02-02 00:00:009, Place Louis BarthouBordeauxNoneFrance330003.96
10462021-02-03 00:00:003 Chatham StreetDublinDublinIrelandNone5.94
... more rows ...

You can preview select statements before fetching data to your variables.

table.select("InvoiceId", "CustomerId", "BillingAddress", "BillingCountry", "Total")\
    .where\
        .gte("Total", 2.0)\
    .then\
        .order_by("CustomerId")\
        .limit(10)
Invoice
InvoiceIdCustomerIdBillingAddressBillingCountryTotal
981Av. Brigadeiro Faria Lima, 2170Brazil3.98
1211Av. Brigadeiro Faria Lima, 2170Brazil3.96
1431Av. Brigadeiro Faria Lima, 2170Brazil5.94
3271Av. Brigadeiro Faria Lima, 2170Brazil13.86
3821Av. Brigadeiro Faria Lima, 2170Brazil8.91
122Theodor-Heuss-Straße 34Germany13.86
672Theodor-Heuss-Straße 34Germany8.91
2192Theodor-Heuss-Straße 34Germany3.96
2412Theodor-Heuss-Straße 34Germany5.94
9931498 rue BélangerCanada3.98

Purpose

It's a tiny little modern ORM that lets you prototype your databases locally with great flexibility. Also, it can be used in production apps to store and retrieve data, because all select, update, delete queries are parametrized. But it does not restrict you from using your own queries which might not be paramerized with methods like select.custom() and where.custom().

And last (but not least) is data inspection. If you need to quickly inspect existing .db file but don't want to install yet another heavy ORM with a lot of unused dependencies, you might look into Sql-Engine, as it uses only native python modules.

Installation

To install sqlengine, you can use pip:

pip install sqlengine-lite

Env

You may set environment variable for logging. By default it's WARNING.

SQL_ENGINE_LOG_LEVEL=INFO

Quick Start

All you have to do to create your own cute little table is to inherit SqlTableMixin class or to create your own schema and declare desired properties of your table's columns. They are:

Name of the table that will be used in queries. If omitted in inherited class declaration, then it will take the class name.

__tablename__ : Optional[str]

Column names of the table

__columns__ : list[str] 

Column types of the table

__types__ : list[SqlType | str] 

List of primary keys

__primary__ : list[str] 

Table Declaration

More details at Declaration.

from sqlengine import SqlTableMixin

# Helper constants for column names
ID = "ID"
Name = "Name"
Occupation = "Occupation"
Salary = "Salary"


class Employees(SqlTableMixin):

    __columns__   = [ID, Name, Occupation, Salary]
    __types__     = [int, str, str, float]
    __primary__   = [ID]

    # You may overwrite your insert methods for type consistency
    def insert(self, id : int, name : str, occupation : str, salary : float) -> None:
        return super().insert(id, name, occupation, salary)
    
    def upsert(self, id : int, name : str, occupation : str, salary : float) -> None:
        return super().upsert(id, name, occupation, salary)

Instantiation

More details at Instantiation.

# Create an instance of the table class 
# with provided path to create or connect to

table = Employees("temp/data.db")

Row insertion

# Insert one row

table.insert(1, "John Doe", "Software Engineer", 75000.0)
# Bulk insert multiple rows

employees_data = [
    (2, "Jane Smith", "Data Scientist", 80000.0),
    (3, "Alice Johnson", "Product Manager", 90000.0),
    (4, "Bob Brown", "Project Manager", 78000.0),
    (5, "Charlie Davis", "UI/UX Designer", 65000.0),
    (6, "David Wilson", "DevOps Engineer", 82000.0),
    (7, "Eve Taylor", "Customer Support", 45000.0),
    (8, "Frank White", "Quality Assurance", 53000.0),
    (9, "Grace Hall", "Marketing Manager", 68000.0),
    (10, "Henry Lee", "Technical Writer", 52000.0)
]

table.insert_many(employees_data)
# Upsert one row

table.upsert(1, "Jane Doe", "Data Scientist", 80000.0)

Jupyter view

# Inspect tables in Jupyter Notebook

table
Employees
IDNameOccupationSalary
1Jane DoeData Scientist80000.0
2Jane SmithData Scientist80000.0
3Alice JohnsonProduct Manager90000.0
4Bob BrownProject Manager78000.0
5Charlie DavisUI/UX Designer65000.0
6David WilsonDevOps Engineer82000.0
7Eve TaylorCustomer Support45000.0
8Frank WhiteQuality Assurance53000.0
9Grace HallMarketing Manager68000.0
10Henry LeeTechnical Writer52000.0

Select Query

More details at Statements.

# Query select and fetch

table.select.where.between(ID, 3, 5).then.fetchall()

# ->
# [(3, 'Alice Johnson', 'Product Manager', 90000.0),
#  (4, 'Bob Brown', 'Project Manager', 78000.0),
#  (5, 'Charlie Davis', 'UI/UX Designer', 65000.0)]
# Inspect query select in Jupyter

table.select(Name, Salary).where.lt(Salary, 70_000)
Employees
NameSalary
Charlie Davis65000.0
Eve Taylor45000.0
Frank White53000.0
Grace Hall68000.0
Henry Lee52000.0

Update Query

# equal to ...update.set(Salary, 50_000)...
table.update(Salary, 50_000).where.eq(Name, "Eve Taylor").then.execute()

Delete Query

table.delete.where.eq(ID, 5).then.execute()

Transaction

More details at Transaction.

# Operate within a transaction

with table.transaction():
    for row in employees_data:
        table.upsert(*row)

Get Item

More details at Syntax Sugar.

# Fetch row by primary key

table[9]

# -> (9, 'Grace Hall', 'Marketing Manager', 68000.0)
# Fetch slice by integer primary key

table[4:10:2]

# -> 
# [(4, 'Bob Brown', 'Project Manager', 78000.0),
#  (6, 'David Wilson', 'DevOps Engineer', 82000.0),
#  (8, 'Frank White', 'Quality Assurance', 53000.0)]

Csv Converter

# Save table to csv
from sqlengine.utils import to_csv

to_csv(table, "temp/table.csv")
# Save query result to csv

to_csv(table.select.where.gt(Salary, 70_000), "temp/query.csv")

Full Documentation

For detailed usage, API reference, and advanced examples, see the full documentation.

Project details


Download files

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

Source Distribution

sqlengine_lite-2.1.1.tar.gz (25.8 kB view details)

Uploaded Source

Built Distribution

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

sqlengine_lite-2.1.1-py3-none-any.whl (20.0 kB view details)

Uploaded Python 3

File details

Details for the file sqlengine_lite-2.1.1.tar.gz.

File metadata

  • Download URL: sqlengine_lite-2.1.1.tar.gz
  • Upload date:
  • Size: 25.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for sqlengine_lite-2.1.1.tar.gz
Algorithm Hash digest
SHA256 dd805d5a76b38196a581c75fe95b036a9bedc9822f42010fb32b5a388d92dba9
MD5 5ad173762bf368c50cd85d54a09b3b97
BLAKE2b-256 7b63dfaf9ea8b1dbe98da681315eaae85b571c8f50168eebd677ffefcd3794dc

See more details on using hashes here.

Provenance

The following attestation bundles were made for sqlengine_lite-2.1.1.tar.gz:

Publisher: publish.yml on suffermuffin/SQL-Engine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sqlengine_lite-2.1.1-py3-none-any.whl.

File metadata

  • Download URL: sqlengine_lite-2.1.1-py3-none-any.whl
  • Upload date:
  • Size: 20.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for sqlengine_lite-2.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 2517d2e5f0940a1c00b0ff2f206cec797ef4b2aed69601f4531a7e2fd40a3865
MD5 edfac0c6c4e1a3d7138021b998de7997
BLAKE2b-256 dba9bae2f8afc0bc211f488396f5f7429aed5ee82bb5d14e3ae3f9b97c710a09

See more details on using hashes here.

Provenance

The following attestation bundles were made for sqlengine_lite-2.1.1-py3-none-any.whl:

Publisher: publish.yml on suffermuffin/SQL-Engine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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