pgvector-python
Python client library for pgvector: vector, halfvec, sparsevec, and bit types across Django, SQLAlchemy, Psycopg, asyncpg, pg8000, and Peewee.
Repository Health
Technical Analysis
pgvector-python is the official Python integration for the pgvector Postgres extension, the vector-similarity-search engine that runs as a native Postgres type instead of a separate vector database. Rather than shipping one API, the library ships an adapter per data-access layer: typed fields and query expressions for Django and SQLAlchemy/SQLModel, connection-level type registration for Psycopg 3, Psycopg 2, asyncpg, and pg8000, and field classes for Peewee.
Across every adapter it exposes the same four Postgres types pgvector defines — full-precision vector, half-precision halfvec, sparse sparsevec, and bit for binary embeddings — plus the distance operators (L2, cosine, inner product, L1, Hamming, Jaccard) needed to build a nearest-neighbor query in each ORM’s native query syntax. It handles the wire-format conversion (text and binary) between Python lists/NumPy arrays and Postgres vector literals, so application code works with plain lists or ndarrays and never touches the encoding directly.
What You Get
- Native field/column types for Django, SQLAlchemy, SQLModel, and Peewee, so vector columns are declared and migrated the same way as any other model field
- Connection-level type registration for Psycopg 3/2, asyncpg, and pg8000, converting between Python lists/NumPy arrays and Postgres vector wire format automatically
- Distance operators exposed as query-builder methods —
l2_distance,cosine_distance,max_inner_product,l1_distance,hamming_distance,jaccard_distance— usable in each ORM’s nativeorder_by/filtersyntax - HNSW and IVFFlat approximate-index helpers (
HnswIndex,IvfflatIndexfor Django;Indexconstruction helpers for SQLAlchemy) including half-precision and binary-quantized expression indexes - Optional NumPy and SciPy interop for converting vectors to/from
ndarrayand sparse matrix representations without manual (de)serialization
Common Use Cases
- Storing LLM/embedding-model output (OpenAI, Cohere, SentenceTransformers, etc.) as native columns on existing Django or SQLAlchemy models instead of standing up a separate vector database
- Building retrieval-augmented generation (RAG) pipelines where document chunks and their embeddings live in the same Postgres instance as the rest of the application data
- Implementing hybrid search — combining full-text and vector similarity, or reciprocal-rank-fusion / cross-encoder re-ranking — using SQL that already integrates with an existing ORM’s transactions and migrations
- Reducing index size and query latency with half-precision (
halfvec) or binary-quantized (bit+ Hamming distance) vector representations for large embedding collections
Under The Hood
Architecture
The library is organized as one adapter package per data-access layer (pgvector.django, pgvector.sqlalchemy, pgvector.psycopg, pgvector.psycopg2, pgvector.asyncpg, pgvector.pg8000, pgvector.peewee) sitting on top of four shared, adapter-agnostic value types in the package root (Vector, HalfVector, SparseVector, Bit, in pgvector/vector.py, halfvec.py, sparsevec.py, bit.py). Each value type owns its own text and binary (de)serialization (_to_db/_from_db, to_binary/from_binary in vector.py) so every adapter converts through the same code path rather than reimplementing wire-format logic. Adapters then layer driver-specific concerns on top: psycopg/register.py fetches each type’s OID via TypeInfo.fetch and registers dumpers/loaders per connection (with an async mirror, register_vector_async, for AsyncConnection), while sqlalchemy/vector.py implements a UserDefinedType with bind_processor/result_processor hooks and a Comparator subclass that maps l2_distance/cosine_distance/etc. onto Postgres’s <->/<=>/<#>/<+> operators, registering itself into SQLAlchemy’s ischema_names for reflection. A change to the underlying vector encoding only needs to happen once in the root value types; each adapter’s job is limited to plugging that encoding into its driver’s type-registration hooks.
Tech Stack
Pure Python (99.9% of the codebase) targeting Python >= 3.10, built with a standard setuptools backend and zero runtime dependencies of its own — instead it declares each supported library (Django, SQLAlchemy >= 2 with asyncio extras, Psycopg 3 with binary/pool extras, psycopg2-binary, asyncpg, pg8000, Peewee, SQLModel, NumPy, SciPy) as optional dev/extra dependency groups (pyproject.toml’s [dependency-groups]), so consumers only install the adapter their stack needs. Distance and array conversion are implemented with the standard-library array and struct modules rather than NumPy, keeping the core adapters dependency-free while still offering NumPy/SciPy interop (to_numpy, ndarray construction) when those packages are present.
Code Quality
Each adapter has a dedicated test module under tests/ (test_django.py, test_sqlalchemy.py, test_psycopg.py, test_asyncpg.py, test_pg8000.py, test_peewee.py, test_sqlmodel.py, plus test_vector.py/test_half_vector.py/test_sparse_vector.py/test_bit.py for the shared value types), run via pytest with pytest-asyncio for the async adapters. CI (.github/workflows/build.yml) builds pgvector itself from source across two Python versions (3.10 and 3.14), runs the full test suite once with and once without NumPy/SciPy installed, then runs both mypy --strict and ty check — the codebase carries a py.typed marker and every public function in the sampled modules (vector.py, register.py) is fully typed with modern syntax (list[float] | ndarray, /-only positional parameters).
What Makes It Unique
The distinguishing design choice is treating vector support as a set of thin, type-system-native adapters instead of a query-building abstraction layer of its own: a VectorField in Django is a normal Django field usable with order_by/annotate/filter, and a VECTOR column in SQLAlchemy is a normal UserDefinedType usable with the ORM’s existing Index, Comparator, and reflection machinery — so pgvector-backed similarity search composes directly with each framework’s transactions, migrations, and query builder rather than requiring a separate client or query language.
Used by 15 apps in this directory
Langflow
AI Agents · AI Development
Build, test, and deploy AI agents and RAG workflows visually with native API and MCP server export.
LearnHouse
CMS · Learning Management
Open-source LMS with AI tutoring, real-time collaboration boards, live code execution, and built-in course monetization — self-hosted in minutes.
Morphik
AI Development · Databases · Search
Morphik is an AI-native ingestion and retrieval engine that lets developers store, search, and reason over visually rich documents — scanned PDFs, manuals, slides, and video — without duct-taping together OCR, an embedding model, and a vector database.
Open WebUI
AI Agents · AI Assistants
The extensible, privacy-first AI platform that runs Ollama, OpenAI, and any LLM backend behind a polished, feature-packed web interface.
Stirling PDF
Digital Signiture · Productivity
The open-source PDF platform you can run anywhere — edit, convert, sign, and automate PDFs without sending files to external servers.
SurfSense
AI Assistants · Search
The open-source, unlimited NotebookLM alternative with real-time collaboration, a desktop app, and no vendor lock-in.