Skip to main content

SQL for Humans enhanced.

Project description

PyPI CI Coverage License

ezrecords is a very simple, but powerful, library for making raw SQL queries to most relational databases.

ezrecords = Kenneth Reitz’s records + Justin Vincent’s ezsql + WordPress’ wpdb - SQLAlchemy.

Just write SQL. No bells, no whistles. This common task can be surprisingly difficult with the standard tools available. This library strives to make this workflow as simple as possible, while providing an elegant interface to work with your query results.

Database support includes SQLite, Postgres, and MySQL (drivers not included).

Why?

  • records is awesome

  • ezsql and wpdb have very nice API, so it makes for an easy transition from PHP to Python

  • Our love for crafting well written and performant SQL queries is not questionable, but I think a few helpers for some basic DML and recurring queries would help

  • “The ORM takes two brilliant ideas and incapacitates them both.”, said a very wise man. So, as long as possible I want to keep away from SQLAlchemy or the like.

Usage

API

import logging
from ezrecords.mysqldb import MySQLDb

logger = logging.getLogger()

# connect
db = MySQLDb(db_url="mysql://root:passwd@127.0.0.1:3306/test", logger=logger) # logger is optional

# enable debugging - optional
db.save_queries = True  # save queries and execution time
db.show_sql = True  # show SQL code being executed. logger above is required for logging to work
db.show_errors = True  # show errors

create_user_table = """
CREATE TABLE test_user (
    id INT AUTO_INCREMENT NOT NULL,
    username varchar(255) UNIQUE,
    password varchar(255),
    created_at TIMESTAMP,
    created_at_gmt TIMESTAMP,
    PRIMARY KEY(id)
)
"""
db.query(create_table) # run generic SQL

create_numbers_table = """
DROP TABLE IF EXISTS numbers;
CREATE TABLE numbers(
    ints int,
    floats float
);
"""
db.query(create_table_sql)

insert_numbers_sql = "INSERT INTO numbers (ints, floats) VALUES (%d, %f)" # DB API only accepts %s, so we replace %d and %f by %s internally
db.query(insert_numbers_sql, 3, 3.14) # run generic queries with params

# insert records
db.insert('test_user', username='scott', password='tiger', created_at=datetime.datetime.now())
db.insert('test_user', {'username': 'JONES', 'password': 'STEEL'})

# bulk_insert records
db.bulk_insert('test_user', ('username', 'password'), [('scott', 'tiger'), ('JONES', 'STEEL')])

# Update records
db.update('test_user', {'password': 'shepard'}, {'username': 'scott'})

# Delete records
db.delete('test_user', {'username': None}) # None is converted to NULL

# Sanitize query
db.prepare("""INSERT INTO postmeta (post_id, meta_key, meta_value) VALUES ( '%d', "%s", %%s )')""", 10, "Harriet's Adages", "WordPress' database interface is like Sunday Morning: Easy.")

# Call stored procedures
db.call_procedure('adds', 1, 2)

# Get single variable/value
db.get_var('SELECT version()')

# Get specific row from many results
db.get_row('SELECT * FROM test_user', row_offset=1) # if offset not given the first row is returned

# Get specific column from many results
db.get_col('SELECT username, password FROM test_user', column_offset='password')  # offset can be numeric too

# Get results in specific format
db.get_results('SELECT username, password FROM test_user', 'json')
# Get last inserted ID from AUTO_INCREMENT/SERIAL fields
db.insert('test_user', username='scott', password='tiger', created_at=datetime.datetime.now())
db.last_insert_id

# Get number of affected rows from previus query
db.delete('test_user')
db.affected_rows

# Switch to another database
db.use('information_schema')

# Check query timing
# execute long running query
db.last_query_elapsed_time

# Transactions
# ---
db.begin_transaction()
db.commit() # or db.rollback()

# Data export
rows = db.query('SELECT * FROM table')
rows.dataset
rows.export('csv') # yaml, json, xls, xlsx

# Goodies
db.db_version() # get server version
db.exists('table') # check if table exists
db.get_table_names() # get list of tables in database
db.flush() # clear cache results

CLI

As an added bonus, a records command-line tool is automatically included. Here’s a screenshot of the usage information:

CLI

Here’s some usage example

ezrecords -h
ezrecords "SELECT version() AS version" "json" --url="mysql://root:passwd@127.0.0.1:3306/test"
ezrecords "SELECT version() AS version" "json" --url="postgres://postgres:passwd@127.0.0.1:5432/test"
ezrecords "SELECT sqlite_version() AS version" "json" --url="sqlite:///:memory:"

Installation

pip install ezrecords

ezrecords runs on Python 3.11.

Documentation Generation

# edit documentation in _docs
cd _docs
make singlehtml
cd ..
cp -fR _docs/_build/singlehtml/* docs/

Thank you

Thanks for checking this library out! I hope you find it useful.

Of course, there’s always room for improvement. Feel free to open an issue so we can make ezrecords better, faster, and stronger.

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

ezrecords-1.1.0.tar.gz (189.4 kB view details)

Uploaded Source

Built Distribution

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

ezrecords-1.1.0-py3-none-any.whl (192.0 kB view details)

Uploaded Python 3

File details

Details for the file ezrecords-1.1.0.tar.gz.

File metadata

  • Download URL: ezrecords-1.1.0.tar.gz
  • Upload date:
  • Size: 189.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for ezrecords-1.1.0.tar.gz
Algorithm Hash digest
SHA256 529c2f8123a135dc8f1204ed69a90ad8eaa075084a8f660af55c043a017f529b
MD5 8a5f4f2feb625bc10129b1a794c05e76
BLAKE2b-256 e526587f6248bb8ecdd619f264e042e3f8dd33d8f97e50ee75cba442c681bc4b

See more details on using hashes here.

File details

Details for the file ezrecords-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: ezrecords-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 192.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for ezrecords-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 337cc88ce4416f3be6a69f339bbd83033728b5d6aa0afbc18f48420d6ced5020
MD5 3d22ff8aa20d7f866500b1bf2c9f1986
BLAKE2b-256 149f42ff6b499abaad324cc2e334de72f9ce4fff1ba56c7e3b2ba5043c8c91f8

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