Core/ORM select(), DDL (CREATE TABLE/CREATE INDEX), reflection, and Alembic migrations all go through the standard SQLAlchemy surface — vector search is just .order_by(column.cosine_distance(q)), spelled exactly like pgvector's own comparator. Joins, grouped aggregates, subqueries and relationship .any()/.has() (correlated EXISTS, decorrelated into a semi/anti join) run through the DBAPI's relational planner; a sa.Text column is Milvus's full-text input (analyzer-enabled), ready for a BM25-generated sparse field.
Installation
pip install milvusql-sqlalchemy
Quick start
from sqlalchemy import create_engine, select
from milvusql_sqlalchemy.types import VECTOR
engine = create_engine("milvusql:///items.db") # Milvus Lite, or a real server's URI
with engine.connect() as conn: # items: Table with an `embedding` VECTOR column
rows = conn.execute(
select(items.c.id, items.c.category)
.order_by(items.c.embedding.l2_distance([0.1] * 768))
.limit(5)
).all()
The same engine, asyncio-native, via create_async_engine and the milvusql+aio driver:
from sqlalchemy.ext.asyncio import create_async_engine
engine = create_async_engine("milvusql+aio:///items.db")
async with engine.connect() as conn:
rows = (
await conn.execute(
select(items.c.id).order_by(items.c.embedding.cosine_distance(q)).limit(5)
)
).all()
Connection URLs
milvusql:///items.db # Milvus Lite -- relative file path
milvusql:////abs/path/items.db # Milvus Lite -- absolute file path
milvusql://user:password@host:19530/db_name # a real server
milvusql://user:password@host:19530/db_name?secure=1 # TLS (https)
milvusql+aio://... # same URL forms, async engine
API
VECTOR(dim) / SPARSEVEC
from sqlalchemy import Column, Table
from milvusql_sqlalchemy.types import VECTOR, SPARSEVEC
items = Table(
"items", metadata,
Column("id", BigInteger, primary_key=True, autoincrement=True),
Column("embedding", VECTOR(768)),
Column("sparse", SPARSEVEC),
milvusql_shards=1,
milvusql_consistency_level="Strong",
)
| Comparator method | MilvusQL operator | Available on |
|---|---|---|
.l2_distance(other) |
<-> |
VECTOR |
.cosine_distance(other) |
<=> |
VECTOR |
.l1_distance(other) |
<+> |
VECTOR |
.max_inner_product(other) |
<#> |
VECTOR, SPARSEVEC |
Bind values pass through as plain list[float] — never stringified into SQL text.
hybrid_search()
Weighted multi-vector search, rendered where MilvusQL's HYBRID SEARCH ... RERANK ... sits — in place of ORDER BY:
from milvusql_sqlalchemy.hybrid import hybrid_search, weighted
select(items.c.id).order_by(
hybrid_search(
weighted(items.c.embedding.cosine_distance(dense_q), 0.7),
weighted(items.c.sparse.max_inner_product(sparse_q), 0.3),
rerank="RRF", k=60,
)
).limit(10)
DDL options
Dialect-specific Table/Index arguments, the same mechanism as mysql_engine=...:
Table(
"items", metadata, ...,
milvusql_shards=2,
milvusql_consistency_level="Bounded",
milvusql_partition_key="category",
)
Index(
"idx_embedding", items.c.embedding,
milvusql_using="HNSW",
milvusql_with={"metric_type": "COSINE", "M": 16, "ef_construction": 200},
)
Consistency level
A statement's own CONSISTENCY LEVEL clause always wins; otherwise the engine falls back to the connection's isolation level — one of Milvus's own levels (Strong, Bounded, Eventually, Session, Customized), set the normal SQLAlchemy way:
conn = engine.connect().execution_options(isolation_level="Bounded")
Alembic
Importing this dialect registers milvusql's DefaultImpl with Alembic automatically — alembic upgrade/downgrade work against a milvusql://... URL with no extra setup. Non-transactional (transactional_ddl = False): Milvus has no multi-statement rollback, so a failed migration can't be undone by Alembic — write forward-only migrations.
Examples
| Example | Shows |
|---|---|
examples/fastapi_image_search |
A FastAPI service for image search: insert images with a caption, search by query image or free text (cross-modal, via CLIP), delete |
examples/pydantic_ai_agent |
A pydantic-ai shopping-assistant agent whose only access to the catalog is through typed tools backed by a real vector search |
Development
From the workspace root (requires Python 3.12+, uv, task):
task install
task sqlalchemy:lint
task sqlalchemy:test # integration tests need Docker (testcontainers)
License
MIT
Metadata
Release files for milvusql-sqlalchemy 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| milvusql_sqlalchemy-1.0.0.tar.gz | 16.9 kB | Without provenance | Details for milvusql_sqlalchemy-1.0.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| milvusql_sqlalchemy-1.0.0-py3-none-any.whl | Python 3 | none | any | Details for milvusql_sqlalchemy-1.0.0-py3-none-any.whl |
Total release size: 38.0 kB
Release files / milvusql_sqlalchemy-1.0.0.tar.gz
| Download URL | milvusql_sqlalchemy-1.0.0.tar.gz |
|---|---|
| Size | 16.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3405e8b467acce5d28ace8b625348129341bd3af6cc015df7603ff18b3d76b21
|
|
BLAKE2b-256 checksum How to use checksums |
2b0c481467b1f621f71f082301e6e9a74c0d735b11e6caf92de3e31a3c1ea709
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / milvusql_sqlalchemy-1.0.0-py3-none-any.whl
| Download URL | milvusql_sqlalchemy-1.0.0-py3-none-any.whl |
|---|---|
| Size | 21.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0bb17c20930965131a9e8d300e6c63020495fa53c6c317c87170936adbbc119a
|
|
BLAKE2b-256 checksum How to use checksums |
8a5082943283c98b7e5833513f191c5b5e5fd078926a738afe84ce4e46873e20
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for milvusql-sqlalchemy 1.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.