pgvector-python for PostgreSQL Vector Search
pgvector support for Python
At a glance
- What is it?
- pgvector-python is a Python integration library for the pgvector PostgreSQL extension. It adds vector fields, distance operators, similarity queries, and approximate indexes across Django, SQLAlchemy, SQLModel, Psycopg, asyncpg, pg8000, and Peewee.
- Who is it for?
- Adopt pgvector-python when the application already uses PostgreSQL and needs vector storage or nearest-neighbor queries through a supported Python database layer. Do not choose it as a standalone vector database or embedding generator, and first verify the required pgvector extension, database driver, vector field type, distance operator, and index configuration in the target PostgreSQL environment.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
PostgreSQL Vector Search from Python
pgvector-python solves a database integration problem rather than a model-building problem. It provides Python bindings for PostgreSQL vector types and query operations so an application can store embeddings, compare them with a query vector, filter by distance, and define approximate indexes. The README lists support for Django, SQLAlchemy, SQLModel, Psycopg 3, Psycopg 2, asyncpg, pg8000, and Peewee. That range makes the library relevant when an application has several database access layers or when developers want vector search to remain in PostgreSQL instead of moving vector data to a separate search service.
The library does not create embeddings by itself. The README examples connect it to external systems such as Ollama, OpenAI, Cohere, SentenceTransformers, and ColBERT, but those are separate components. The core package supplies database types, expressions, aggregate functions, and index declarations. This distinction matters when evaluating adoption: the application still needs an embedding source, and PostgreSQL needs the pgvector extension available.
Vector Types, Distances, and Indexes
The documented mechanisms follow PostgreSQL and pgvector concepts. A Python field can represent a vector, and the framework-specific API exposes distance expressions such as L2, maximum inner product, cosine, L1, Hamming, and Jaccard distance. A typical query orders rows by a distance expression and limits the result. A second query pattern annotates the calculated distance, which allows a caller to inspect the score. A filter such as distance less than a chosen threshold restricts the result set to vectors within that boundary.
The README also documents aggregates including `Avg` in Django and `avg` in SQLAlchemy, with `Sum` support as well. Approximate indexes are exposed as `HnswIndex` and `IvfflatIndex` in Django and through SQLAlchemy index definitions. The README associates `vector_l2_ops` with L2 indexing, `vector_ip_ops` with inner product, and `vector_cosine_ops` with cosine distance. These choices are part of the database design rather than Python configuration alone. A field declared as `VECTOR(3)` or `VectorField(dimensions=3)` has a fixed dimension, so schema dimensions must match the embeddings used by the application.
Half-precision indexing is a separate trade-off. The Django documentation shows casting an embedding to `HalfVectorField` for an HNSW index using `halfvec_l2_ops`. That changes storage and indexing behavior, so it should be considered explicitly rather than treated as a transparent replacement for the full vector column.
Installing pgvector-python in a Django Project
The README gives one installation command. The package metadata declares Python 3.10 or newer and identifies the distribution as `pgvector`, so the first step is to install that distribution in the environment used by the application.
pip install pgvectorAfter installation, the Django integration requires a migration operation that enables the PostgreSQL extension. The documented operation is `VectorExtension`, imported from `pgvector.django`. The migration needs the surrounding Django migration structure, including the usual `migrations` module and imports.
from pgvector.django import VectorExtension
class Migration(migrations.Migration):
operations = [
VectorExtension()
]The project database also needs to be the PostgreSQL database used by the surrounding application. The README does not document database creation, connection, or extension-installation server commands, so those steps must come from the application's existing Django and PostgreSQL configuration.
Defining, Writing, and Querying a Django Vector Field
A Django model can define an embedding with an explicit dimension. The README uses three dimensions in its example, which keeps the example small but also demonstrates the fixed-size contract. Other documented fields are `HalfVectorField`, `BitField`, and `SparseVectorField`.
from pgvector.django import VectorField
class Item(models.Model):
embedding = VectorField(dimensions=3)The application can assign a Python list and save the model normally. The ORM serializes the value for the PostgreSQL column, while the vector dimension in the model controls the expected shape.
item = Item(embedding=[1, 2, 3])
item.save()Nearest-neighbor search is expressed as an ordered Django queryset. `L2Distance` compares the stored `embedding` with a query vector, and slicing returns the first five records.
from pgvector.django import L2Distance
Item.objects.order_by(L2Distance('embedding', [3, 1, 2]))[:5]This example is a real application path only after the migration and database connection are in place. It also shows that the package does not hide vector search behind a separate service. The query travels through Django to PostgreSQL.
SQLAlchemy and SQLModel Integration Boundaries
For SQLAlchemy, the README requires enabling the extension with SQL executed through the session, then defining a column with a pgvector type. The documented column uses `VECTOR(3)` and maps it to `list[float]`. Other supported types are `HALFVEC`, `BIT`, and `SPARSEVEC`.
session.execute(text('CREATE EXTENSION IF NOT EXISTS vector'))from pgvector.sqlalchemy import VECTOR
class Item(Base):
embedding: Mapped[list[float]] = mapped_column(VECTOR(3))The query API is expressed on the mapped column. For example, the application can order by `l2_distance`, apply a limit, select the distance value, or filter on a threshold. The SQLAlchemy integration also supports `max_inner_product`, `cosine_distance`, `l1_distance`, `hamming_distance`, and `jaccard_distance`.
The same package supports SQLModel, but the README does not provide a complete SQLModel-specific example. It does establish SQLModel as a supported integration and lists SQLModel in the development dependencies. That is enough to identify compatibility, but not enough to document exact SQLModel declarations beyond the SQLAlchemy examples. Developers using that integration should verify the SQLAlchemy behavior against their model's mapped field and the installed framework version.
The package metadata has no runtime dependencies and leaves database-driver installation to the application. SQLAlchemy, Psycopg, asyncpg, pg8000, and other drivers appear in development dependency groups for the repository's own checks, but users still need the driver and database configuration required by their application.
Operational Limits and the Direct SQL Alternative
The most important limitation is architectural. pgvector-python is not a replacement for the PostgreSQL pgvector extension, and it does not supply a standalone vector database. The application must have a compatible PostgreSQL deployment, the vector extension, a supported Python integration, and an embedding source. A failure in any of those layers can prevent the ORM examples from working even though the Python package itself imports.
The fixed vector dimension is another constraint. Changing an embedding model can require a schema change, a data conversion, and index review. The documented half-precision example does not remove that design work because it uses a cast and a separate `halfvec_l2_ops` operator class.
A real alternative is to interact with PostgreSQL directly through the database driver and SQL, instead of using pgvector-python's ORM-specific fields and query expressions. The README shows direct session execution for extension setup, so the difference is concrete. Direct SQL leaves column declarations, vector values, operators, and query construction in application SQL, while pgvector-python maps them into Django, SQLAlchemy, and the other supported libraries. For a project that already has an established ORM abstraction, the library reduces custom SQL and keeps vector operations in the same model layer. For a project that needs a SQL shape the adapter does not expose, direct SQL may be clearer, but the pgvector extension and PostgreSQL deployment remain necessary.
Maintenance, Packaging, and License Context
The repository is not archived, and its last push was on 2026-10-14. There are no GitHub releases listed, so the repository history does not establish a release-based upgrade policy. The current package metadata declares version `0.5.1`, requires Python `>= 3.10`, and has no runtime dependencies. Development dependencies include database libraries, test runners, type checkers, and optional scientific packages such as NumPy and SciPy. Those groups describe development tooling and are not additional requirements automatically installed with `pip install pgvector`.
The project is licensed under MIT. That identifier is useful when reviewing distribution terms, but it is not a substitute for reviewing the license file and any obligations associated with the selected version. Upgrade cost appears low for applications that already meet the Python requirement and use the documented integrations, yet compatibility still needs checking against the PostgreSQL deployment, pgvector extension, database driver, ORM version, and embedding dimensions.
The repository also includes examples for retrieval-augmented generation, embeddings, hybrid search, sparse search, late interaction search, image search, recommendations, bulk loading, and Citus. Those examples demonstrate possible application areas, but the README does not claim that every example is a supported production architecture. The package itself remains the focused choice for Python access to pgvector.
Editorial conclusion
Adopt pgvector-python when the application already uses PostgreSQL and needs vector storage or nearest-neighbor queries through a supported Python database layer. Do not choose it as a standalone vector database or embedding generator, and first verify the required pgvector extension, database driver, vector field type, distance operator, and index configuration in the target PostgreSQL environment.
Frequently asked questions
How do I install pgvector-python?
Install the distribution with `pip install pgvector`. The package metadata requires Python 3.10 or newer, and the database integration also requires a PostgreSQL setup with the pgvector extension.
Which Python database libraries does pgvector-python support?
The README lists Django, SQLAlchemy, SQLModel, Psycopg 3, Psycopg 2, asyncpg, pg8000, and Peewee. The package provides integrations for these libraries, while the application still needs its own database driver and connection configuration.
How do I perform nearest-neighbor search with pgvector-python?
In Django, order a queryset with an expression such as `L2Distance('embedding', [3, 1, 2])` and slice the result. In SQLAlchemy, use the mapped column's `l2_distance` expression with `order_by` and `limit`.
Does pgvector-python create embeddings automatically?
No. The package supplies PostgreSQL vector types, distance expressions, aggregates, and index declarations. The README's examples use separate tools such as Ollama, OpenAI, Cohere, SentenceTransformers, or ColBERT to produce embeddings.
What database and extension setup is required?
The documented Django integration uses a migration containing `VectorExtension()`, and the SQLAlchemy example executes `CREATE EXTENSION IF NOT EXISTS vector`. The README does not include server installation commands for PostgreSQL or pgvector.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/pgvector-pgvector-python)