Lightweight Python ORM library for PostgreSQL
Project description
dbentity
Lightweight Python ORM library for PostgreSQL.
Installation
pip install dbentity
Features
- Declarative entity definitions with typed attributes
- Automatic SQL query generation
- Support for JOIN operations
- Query builder with boolean logic (AND, OR, NOT)
- Database migration support
- No external dependencies
Quick Start
from dbentity.db_entity import DbEntity
from dbentity.attribute import IndexAttribute, StringAttribute, IntegerAttribute
from dbentity.db_control import OrderByDesc, Limit
class User(DbEntity):
TABLE = 'users'
ITEMS = (
IndexAttribute(),
StringAttribute('name'),
IntegerAttribute('age'),
)
# Query
users = User.db_list(db, OrderByDesc('age'), Limit(10))
user = User.db_get(db, uid=123)
# Create
user = User.create(db, name='Jane', age=25)
# Update
user.age = 26
user.db_save(db)
# Delete
user.db_delete(db)
Modules
dbentity.entity
Base entity class for data objects.
| Class | Description |
|---|---|
Entity |
Base class. Define attributes via ITEMS tuple. |
EntityError |
Base exception. |
dbentity.db_entity
Entity with database operations.
| Class | Description |
|---|---|
DbEntity |
Entity with CRUD operations. Requires TABLE attribute. |
DbEntityError |
Database entity exception. |
DbEntity Methods:
| Method | Description |
|---|---|
db_list(db, *args, **kwargs) |
Return list of matching entities. |
db_get(db, *args, **kwargs) |
Return first matching entity or None. |
db_count(db, *args, **kwargs) |
Return count of matching rows. |
db_exists(db, *args, **kwargs) |
Return True if any match exists. |
create(db, **kwargs) |
Create and return new entity. |
db_save(db) |
Insert or update entity. |
db_insert(db) |
Insert entity. |
db_update(db) |
Update modified attributes. |
db_delete(db) |
Delete entity. |
delete_by(db, *args, **kwargs) |
Delete matching rows. |
Attributes
dbentity.attribute
| Attribute | Description |
|---|---|
IndexAttribute(name='uid', db_key='id') |
Primary key (not in INSERT/UPDATE). |
CreateIndexAttribute() |
Primary key included in INSERT. |
StringAttribute(name) |
Text field. |
IntegerAttribute(name, minimal=None, maximal=None) |
Integer with optional range. |
FixedPointAttribute(name, fp=2) |
Decimal stored as int (fp=2 → value×100). |
BooleanAttribute(name) |
Boolean field. |
BytesAttribute(name) |
Binary data. |
PasswordAttribute(name) |
Hidden in templates. |
DatetimeAttribute(name) |
Datetime with formatting. |
LastTimeAttribute(name) |
Elapsed time since timestamp. |
ConnectionAttribute(name, sub_entity) |
Foreign key (db_key defaults to {name}_id). |
SubElementsAttribute(name) |
One-to-many (not persisted). |
SumIntegerAttribute(name) |
Integer with SUM aggregation. |
SumFixedPointAttribute(name, fp) |
Fixed-point with SUM aggregation. |
Common parameters:
name- Attribute name in Pythondb_key- Database column name (default: same as name)form_key- Form field name for data bindingdefault- Default value
Query Controls
dbentity.db_control
WHERE Conditions
| Control | SQL | Example |
|---|---|---|
Where(name='John') |
name = 'John' |
Equality |
Where(age=[25,30]) |
age IN (25, 30) |
List → IN |
Where(name=None) |
name IS NULL |
None → IS NULL |
And(a=1, b=2) |
a = 1 AND b = 2 |
AND logic |
Or(Where(a=1), Where(b=2)) |
a = 1 OR b = 2 |
OR logic |
Not(active=True) |
NOT active = true |
Negation |
Lt(age=30) |
age < 30 |
Less than |
Gt(age=18) |
age > 18 |
Greater than |
Le(age=65) |
age <= 65 |
Less or equal |
Ge(age=18) |
age >= 18 |
Greater or equal |
Like(name='John%') |
name LIKE 'John%' |
Pattern match |
ILike(name='%john%') |
name ILIKE '%john%' |
Case insensitive (PostgreSQL) |
IsNull('name') |
name IS NULL |
Explicit NULL check |
IsNotNull('name') |
name IS NOT NULL |
NOT NULL check |
Between('age', 18, 65) |
age BETWEEN 18 AND 65 |
Range |
BitwiseAnd(flags=4) |
flags & 4 > 0 |
Bitwise check |
ORDER, LIMIT, GROUP
| Control | SQL |
|---|---|
OrderBy('name') |
ORDER BY name |
OrderByAsc('name') |
ORDER BY name ASC |
OrderByDesc('age') |
ORDER BY age DESC |
Limit(10) |
LIMIT 10 |
Offset(20) |
OFFSET 20 |
GroupBy('status') |
GROUP BY status |
JOIN
| Control | SQL |
|---|---|
LeftJoin('author') |
LEFT JOIN ... ON ... |
RightJoin('author') |
RIGHT JOIN ... ON ... |
InnerJoin('author') |
INNER JOIN ... ON ... |
FullJoin('author') |
FULL JOIN ... ON ... |
SQL Examples
Basic Queries
# SELECT all
User.db_list(db)
# SQL: SELECT users.id, users.name, users.age FROM users;
# SELECT with WHERE
User.db_list(db, name='John')
# SQL: SELECT ... FROM users WHERE users.name = %s;
# Args: ['John']
# SELECT with multiple conditions
User.db_list(db, name='John', age=30)
# SQL: SELECT ... FROM users WHERE users.name = %s AND users.age = %s;
# Args: ['John', 30]
Comparisons
# Greater than
User.db_list(db, Gt(age=18))
# SQL: SELECT ... FROM users WHERE users.age > %s;
# Args: [18]
# Range with Between
User.db_list(db, Between('age', 18, 65))
# SQL: SELECT ... FROM users WHERE users.age BETWEEN %s AND %s;
# Args: [18, 65]
# IN clause (pass list)
User.db_list(db, age=[25, 30, 35])
# SQL: SELECT ... FROM users WHERE users.age IN (%s, %s, %s);
# Args: [25, 30, 35]
Boolean Logic
# OR
User.db_list(db, Or(Where(name='John'), Where(name='Jane')))
# SQL: SELECT ... FROM users WHERE (users.name = %s OR users.name = %s);
# Args: ['John', 'Jane']
# NOT
User.db_list(db, Not(active=True))
# SQL: SELECT ... FROM users WHERE NOT users.active = %s;
# Args: [True]
# Combined
User.db_list(db, And(Gt(age=18), Lt(age=65)), active=True)
# SQL: SELECT ... WHERE (users.age > %s AND users.age < %s) AND users.active = %s;
Pattern Matching
# LIKE (case sensitive)
User.db_list(db, Like(name='John%'))
# SQL: SELECT ... FROM users WHERE users.name LIKE %s;
# Args: ['John%']
# ILIKE (case insensitive, PostgreSQL)
User.db_list(db, ILike(name='%john%'))
# SQL: SELECT ... FROM users WHERE users.name ILIKE %s;
# Args: ['%john%']
Ordering and Pagination
User.db_list(db, OrderByDesc('age'), Limit(10), Offset(20))
# SQL: SELECT ... FROM users ORDER BY users.age DESC LIMIT 10 OFFSET 20;
JOIN
class Post(DbEntity):
TABLE = 'posts'
ITEMS = (
IndexAttribute(),
StringAttribute('title'),
ConnectionAttribute('author', sub_entity=User),
)
# LEFT JOIN
Post.db_list(db, LeftJoin('author'))
# SQL: SELECT posts.id, posts.title, __author.id, __author.name, __author.age
# FROM posts
# LEFT JOIN users AS __author ON posts.author_id = __author.id;
# JOIN with condition
Post.db_list(db, LeftJoin('author', name='John'))
# SQL: SELECT ... FROM posts
# LEFT JOIN users AS __author ON posts.author_id = __author.id
# WHERE __author.name = %s;
# Args: ['John']
Count and Exists
# Count
User.db_count(db, active=True)
# SQL: SELECT COUNT(*) FROM users WHERE users.active = %s;
# Args: [True]
# Exists
User.db_exists(db, name='John')
# Returns: True/False
Delete
# Delete single entity
user.db_delete(db)
# SQL: DELETE FROM users WHERE id = %s;
# Delete by condition
User.delete_by(db, active=False)
# SQL: DELETE FROM users WHERE users.active = %s;
# Args: [False]
Database Migrations
dbentity.db_upgrade
from dbentity.db_upgrade import db_upgrade
SQL_UPGRADE_FILES = [
(1, 'upgrade_001.sql'),
(2, 'upgrade_002.sql'),
]
db_upgrade(db, log, 'sql/', 'init.sql', SQL_UPGRADE_FILES)
The db_upgrade() function:
- Checks for
db_versiontable - If missing, runs
init.sql(full schema) - If present, runs upgrade files with version > current
- Updates version after each upgrade
License
MIT
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dbentity-1.0.1.tar.gz.
File metadata
- Download URL: dbentity-1.0.1.tar.gz
- Upload date:
- Size: 21.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9def852d7640ad1968a22ce8c5f24d28a11454ee0669f0abf2c520157f9c9db2
|
|
| MD5 |
d8b7433c8bcaa775d506d760637a4279
|
|
| BLAKE2b-256 |
1571b6c3bdc611fe3299612a773f82fe54cb88a861e57475eb02d1221494ff8e
|
Provenance
The following attestation bundles were made for dbentity-1.0.1.tar.gz:
Publisher:
publish.yml on pavelrevak/dbentity
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dbentity-1.0.1.tar.gz -
Subject digest:
9def852d7640ad1968a22ce8c5f24d28a11454ee0669f0abf2c520157f9c9db2 - Sigstore transparency entry: 1203450722
- Sigstore integration time:
-
Permalink:
pavelrevak/dbentity@26f66fb453a08148b3ec42777e25d87c6a66e6f4 -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/pavelrevak
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@26f66fb453a08148b3ec42777e25d87c6a66e6f4 -
Trigger Event:
release
-
Statement type:
File details
Details for the file dbentity-1.0.1-py3-none-any.whl.
File metadata
- Download URL: dbentity-1.0.1-py3-none-any.whl
- Upload date:
- Size: 15.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f4336a9292c936e4b7673a79168d03eb47649e89afc0d9202750bc2485639ded
|
|
| MD5 |
7070ced45e281d824443dbc6835f0e49
|
|
| BLAKE2b-256 |
b90a2f6f5ea6eb7b40cc6c574057d8d2d498094909de27c6e75781342e0b0e2d
|
Provenance
The following attestation bundles were made for dbentity-1.0.1-py3-none-any.whl:
Publisher:
publish.yml on pavelrevak/dbentity
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dbentity-1.0.1-py3-none-any.whl -
Subject digest:
f4336a9292c936e4b7673a79168d03eb47649e89afc0d9202750bc2485639ded - Sigstore transparency entry: 1203450723
- Sigstore integration time:
-
Permalink:
pavelrevak/dbentity@26f66fb453a08148b3ec42777e25d87c6a66e6f4 -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/pavelrevak
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@26f66fb453a08148b3ec42777e25d87c6a66e6f4 -
Trigger Event:
release
-
Statement type: