A schema-flexible, zero-abstraction SQLite interface supporting Relational tables, JSON tables, Full-Text Search, and Semantic Search.
Project description
sqless
A schema-flexible, zero-abstraction SQLite interface supporting Relational tables, JSON tables, Full-Text Search, and Semantic Search.
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 fastersqlessis than the library (i.e., how much slower the library is).↓: How much slowersqlessis than raw SQLite (i.e., the overhead ofsqless).
| 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:
pip install sqless[vec]- Set
SILICON_API_KEYenvironment variable (uses BAAI/bge-m3 embedding model). - 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:
inrequires a list value:[10,12,14]is nullworks, 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
Release history Release notifications | RSS feed
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 sqless-3.0.2.tar.gz.
File metadata
- Download URL: sqless-3.0.2.tar.gz
- Upload date:
- Size: 26.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cdf4c64571c7b66da23f07ae2fcc37f2737156b550043da396d8d2dc08697685
|
|
| MD5 |
8331b49224bfc5e3d6949a8247d67d69
|
|
| BLAKE2b-256 |
2dedc1505a15d165a3f5d7e8282b1af7c15a8a43bc0e4f5de63a48d132664d6b
|
File details
Details for the file sqless-3.0.2-py3-none-any.whl.
File metadata
- Download URL: sqless-3.0.2-py3-none-any.whl
- Upload date:
- Size: 27.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8a99a59c8a87486f0d092807610422592021d97ed6d37b98276d0e783f8ecf8e
|
|
| MD5 |
4bd297fb9c2724efbbdd4e3b5763ae03
|
|
| BLAKE2b-256 |
b42d602c92ba6854edef634783edc16ce7c2d839db24b5e12ed6a5bc837abc7b
|