Skip to main content

A schema-flexible, zero-abstraction SQLite interface supporting Relational tables, JSON tables, Full-Text Search, and Semantic Search.

Project description

sqless

English | 中文版

A schema-flexible, zero-abstraction SQLite interface supporting Relational tables, JSON tables, Full-Text Search, and Semantic Search.

:@sqless


Why sqless is special

  • Schema-free – automatically adjusts the table schema to fit the input data structure.
  • High-performance – executes SQL directly, close to raw SQLite speed, faster than many ORMs.
  • Multi-file sharding – store data across multiple SQLite files easily.
  • SQL-safe – semantic parsing, parameter binding, and identifier validation prevent SQL injection.
  • Multi-table type – supports Relational, JSON, Full-Text Search (FTS), and Vector tables.

⚡ Performance Test

  • Unit: Seconds (lower is better).
  • Percentages indicate the performance difference compared to other libraries.
    • : How much faster sqless is than the library (i.e., how much slower the library is).
    • : How much slower sqless is than raw SQLite (i.e., the overhead of sqless).
Name Init Write Update Read Category
sqlalchemy 0.022 (↑12%) 5.572 (↑94%) 3.218 (↑99%) 58.345 (↑97%) Static schema
dataset 0.030 (↑33%) 10.337 (↑97%) 1.290 (↑98%) 46.209 (↑96%) Flex schema
pony 0.030 (↑34%) 2.221 (↑84%) 0.679 (↑96%) 10.283 (↑84%) Static schema
sqless 0.020 0.359 0.030 1.676 Flex schema
raw sqlite 0.013 (↓51%) 0.260 (↓38%) 0.023 (↓32%) 1.406 (↓19%) Static schema

See benchmark/cmp_with_other_orms.py for details.


🚀 Quick Start

import sqless

db = sqless.DB("your.db")
table = db['users']

table.upsert({
    'U1': {'name': 'Tom', 'age': 14},
    'U2': {'name': 'Jerry', 'age': 12},
})

for item in table.iter('age < 15'):
    print(item)

table['U1']['age'] = 15   # ❌ does NOT update database
table['U1'] = {'age':15}  # ✅ updates database
print(table['U1']) # {'key': 'U1', 'name': 'Tom', 'age': 15}

🧠 Table Types

Table type is determined by prefix:

Type Prefix Features
Relational none low-flexible schema, partial updates
JSON json_ high-flexible schema, full replacement
FTS fts_ full-text search
Vector vec_ semantic search

🔹 Relational Table

table = db['users']
table['U1'] = {'name': 'Tom', 'age': 14}
table['U1'] = {'age': 15}
print(table['U1']) # {'key': 'U1', 'name': 'Tom', 'age': 15}
  • Partial updates: updating one field does not affect others.

See examples/hello-sqless.py for details.


🔹 JSON Table

table = db['json_users']
table['U1'] = {'name': 'Tom', 'age': 14}
table['U1'] = {'age': 15}
print(table['U1']) # {'age': 15}
  • Full replacement: writing field A will overwrite old fields.

See examples/json-table-example.py for details.


🔹 FTS Table (Full-Text Search)

table = db['fts_docs']

table.upsert({
    "A": "SQLite supports full text search"
})

results = table.search('"SQLite"')

See examples/fts-table-example.py for details.


🔹 Vector Table (Semantic Search)

Requirements:

  1. pip install sqless[vec]
  2. Set SILICON_API_KEY environment variable (uses BAAI/bge-m3 embedding model).
  3. Register for SiliconFlow free API if needed: https://cloud.siliconflow.cn/i/szt2CkYN

Usage:

table = db['vec_docs']

table.upsert({
    "A": "Deep learning is part of machine learning"
})

results = table.search("large language model", k=2)

See examples/vec-table-example.py for details.


📁 Multi-file DB

dbs = sqless.DBS(folder="db_folder")

table = dbs["app-Asia-users"]
table.upsert({...})

Mapping rule:

app-Asia-users
↓
app-Asia.sqlite / users

See examples/multi-files-sqless.py for details.


🗂 DB Operations

dir(db)
db.list_tables()
del db['users']
db.close()

See examples/hello-sqless.py for details.


Safe WHERE Expressions

sqless supports safe, parameterized WHERE parsing:

  • Logical operators: AND, OR, NOT
  • Comparison operators: =, ==, !=, <, >, <=, >=, like, ilike, is, in
  • Parentheses: ( and )
  • Sorting: ORDER BY <column> [ASC|DESC]
  • SQL injection safe: forbidden characters ; -- /* */ blocked
  • Values automatically bound with ? placeholders

Example

# Filter age in [10,12,14] or name like 'Tom%', order by age ascending
where_str = "age in [10,12,14] OR name like 'Tom%' order by age asc"
success, sql, params = parse_where(where_str)
print(sql)    # where age in (?,?,?) or name like ? order by age asc
print(params) # [10, 12, 14, 'Tom%']

Notes:

  • in requires a list value: [10,12,14]
  • is null works, e.g., age is null
  • Column names must be valid identifiers (letters, digits, underscores, Chinese characters; cannot start with a digit)
  • Complex SQL functions or subqueries are not supported

🧭 Use Cases

  • Local database tools
  • Data analysis
  • Lightweight services
  • AI applications (RAG / semantic search)

🔄 Migration / Changes

New in this version:

  • vec_ table (semantic search)
  • fts_ table (full-text search)
  • json_ table (high-flexible schema)

Default table type remains Relational (low-flexible schema).


🔹 Legacy Server (Deprecated)

sqless --host 127.0.0.1 --port 12239 --secret xxx
  • Auto creates directories: www/, db/, fs/
  • Access via: http://127.0.0.1:12239/index.html

⚠️ Will be removed in future versions. Current version still compatible.

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

sqless-3.2.1.tar.gz (27.1 kB view details)

Uploaded Source

Built Distribution

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

sqless-3.2.1-py3-none-any.whl (28.9 kB view details)

Uploaded Python 3

File details

Details for the file sqless-3.2.1.tar.gz.

File metadata

  • Download URL: sqless-3.2.1.tar.gz
  • Upload date:
  • Size: 27.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for sqless-3.2.1.tar.gz
Algorithm Hash digest
SHA256 6842a1ac640c3e372be1993c5d97db31107089f0b525231d414ffb54baf47dbe
MD5 443905203fa5237ccb9609d844b52125
BLAKE2b-256 d62feaa02a1e768163807eb88bed510b74131817f473aefe624add312d807e01

See more details on using hashes here.

File details

Details for the file sqless-3.2.1-py3-none-any.whl.

File metadata

  • Download URL: sqless-3.2.1-py3-none-any.whl
  • Upload date:
  • Size: 28.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for sqless-3.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b59af14fbd022dac96afb41b53e071050609aaa91e6c5a365515056fc9b1d250
MD5 2834dd751133ed40545aa34734128adb
BLAKE2b-256 593c3b7be459eaf314ef95d7b0640e993a8ab37058641f6f9fe149494a4f5ed3

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