Skip to content

Commit 86b988f

Browse files
committed
feat!: rename bm25 APIs to paradedb and always use the paradedb access method (paradedb/paradedb#5706)
1 parent 219541e commit 86b988f

12 files changed

Lines changed: 112 additions & 104 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ All notable changes to this project will be documented in this file. The format
66

77
## Unreleased
88

9+
### Changed
10+
11+
- **Breaking**: `BM25Index` is renamed to `ParadeDBIndex`, and indexes are always created with `USING paradedb`. This release requires pg_search 0.25.0+. Update model definitions and existing migrations to the new class name.
12+
913
## [0.10.0] - 2026-07-14
1014

1115
### Removed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636

3737
## ParadeDB for Django
3838

39-
The official [Django](https://www.djangoproject.com/) integration for [ParadeDB](https://paradedb.com) (powered by the [`pg_search`](https://github.com/paradedb/paradedb) Postgres extension), including first-class support for managing BM25 indexes and running queries using the full ParadeDB API. Follow the [getting started guide](https://docs.paradedb.com/documentation/getting-started/environment#django) to begin.
39+
The official [Django](https://www.djangoproject.com/) integration for [ParadeDB](https://paradedb.com) (powered by the [`pg_search`](https://github.com/paradedb/paradedb) Postgres extension), including first-class support for managing ParadeDB indexes and running queries using the full ParadeDB API. Follow the [getting started guide](https://docs.paradedb.com/documentation/getting-started/environment#django) to begin.
4040

4141
## Requirements & Compatibility
4242

examples/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ _The "Hello World" of ParadeDB._
4949

5050
This script demonstrates the fundamental building blocks of search. You will learn how to:
5151

52-
- **Index data**: Define a `BM25Index` on your model.
52+
- **Index data**: Define a `ParadeDBIndex` on your model.
5353
- **Search**: Perform basic keyword queries.
5454
- **Score**: Sort results by relevance (BM25 score).
5555
- **Highlight**: Generate snippets (e.g., `<b>run</b>ning`) to show users why a result matched.

examples/autocomplete/models.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from common import configure_django
44
from django.db import models
55

6-
from paradedb.indexes import BM25Index
6+
from paradedb.indexes import ParadeDBIndex
77
from paradedb.queryset import ParadeDBManager
88
from paradedb.search import Tokenizer
99

@@ -25,7 +25,7 @@ class Meta:
2525
managed = False
2626
db_table = "autocomplete_items"
2727
indexes = (
28-
BM25Index(
28+
ParadeDBIndex(
2929
fields={
3030
"id": {},
3131
"description": {

examples/autocomplete/setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def setup_autocomplete_table() -> int:
1717
from django.db import connection
1818

1919
with connection.cursor() as cursor:
20-
cursor.execute("CREATE EXTENSION IF NOT EXISTS pg_search")
20+
cursor.execute("CREATE EXTENSION IF NOT EXISTS pg_search CASCADE")
2121

2222
# Ensure mock_items exists first
2323
cursor.execute(

examples/common.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import django
1111
from django.conf import settings
1212

13-
from paradedb.indexes import BM25Index
13+
from paradedb.indexes import ParadeDBIndex
1414
from paradedb.queryset import ParadeDBManager
1515
from paradedb.search import Tokenizer
1616

@@ -64,7 +64,7 @@ def setup_mock_items() -> int:
6464
from django.db import connection
6565

6666
with connection.cursor() as cursor:
67-
cursor.execute("CREATE EXTENSION IF NOT EXISTS pg_search")
67+
cursor.execute("CREATE EXTENSION IF NOT EXISTS pg_search CASCADE")
6868
cursor.execute(
6969
"CALL paradedb.create_bm25_test_table("
7070
"schema_name => 'public', table_name => 'mock_items')"
@@ -88,9 +88,9 @@ def setup_mock_items() -> int:
8888
from django.db import models # noqa: E402
8989

9090

91-
def _mock_items_indexes() -> list[BM25Index]:
91+
def _mock_items_indexes() -> list[ParadeDBIndex]:
9292
return [
93-
BM25Index(
93+
ParadeDBIndex(
9494
fields={
9595
"id": {},
9696
"description": {},

paradedb/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
__all__ = [
1515
"Agg",
1616
"All",
17-
"BM25Index",
1817
"Boost",
1918
"Const",
2019
"Exists",
@@ -25,6 +24,7 @@
2524
"MatchAny",
2625
"MoreLikeThis",
2726
"ParadeDB",
27+
"ParadeDBIndex",
2828
"ParadeDBManager",
2929
"ParadeDBQuerySet",
3030
"Parse",
@@ -65,8 +65,8 @@
6565
"paradedb_verify_all_indexes",
6666
),
6767
"paradedb_verify_index": ("paradedb.functions", "paradedb_verify_index"),
68-
"BM25Index": ("paradedb.indexes", "BM25Index"),
6968
"IndexExpression": ("paradedb.indexes", "IndexExpression"),
69+
"ParadeDBIndex": ("paradedb.indexes", "ParadeDBIndex"),
7070
"ParadeDBManager": ("paradedb.queryset", "ParadeDBManager"),
7171
"ParadeDBQuerySet": ("paradedb.queryset", "ParadeDBQuerySet"),
7272
"All": ("paradedb.search", "All"),

paradedb/indexes.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
"""BM25 index support for Django models."""
1+
"""ParadeDB (BM25) index support for Django models."""
22

33
from __future__ import annotations
44

@@ -138,9 +138,9 @@ class IndexExpression:
138138
139139
from django.db.models import F
140140
from django.db.models.functions import Lower
141-
from paradedb.indexes import BM25Index, IndexExpression
141+
from paradedb.indexes import ParadeDBIndex, IndexExpression
142142
143-
BM25Index(
143+
ParadeDBIndex(
144144
fields={"id": {}, "description": {}},
145145
expressions=[
146146
# Text expression with tokenizer
@@ -165,8 +165,12 @@ class IndexExpression:
165165
tokenizer: Tokenizer | None = None
166166

167167

168-
class BM25Index(models.Index):
169-
"""BM25 index for ParadeDB."""
168+
class ParadeDBIndex(models.Index):
169+
"""ParadeDB search (BM25) index.
170+
171+
The index is created with ``USING paradedb``, the index access method
172+
name in pg_search 0.25.0+.
173+
"""
170174

171175
suffix = "bm25"
172176

@@ -218,7 +222,7 @@ def create_sql(
218222
create_stmt += " CONCURRENTLY"
219223
template = (
220224
f"{create_stmt} %(name)s ON %(table)s\n"
221-
"USING bm25 (\n"
225+
"USING paradedb (\n"
222226
" %(expressions)s\n"
223227
")\n"
224228
f"WITH ({', '.join(storage_params)})"
@@ -381,4 +385,4 @@ def _build_json_key_expressions(
381385
return expressions
382386

383387

384-
__all__ = ["BM25Index", "IndexExpression"]
388+
__all__ = ["IndexExpression", "ParadeDBIndex"]

tests/conftest.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def paradedb_ready(django_db_setup: object, django_db_blocker: object) -> None:
6666

6767
with django_db_blocker.unblock(), connection.cursor() as cursor:
6868
try:
69-
cursor.execute("CREATE EXTENSION IF NOT EXISTS pg_search;")
69+
cursor.execute("CREATE EXTENSION IF NOT EXISTS pg_search CASCADE;")
7070
except Exception as exc: # pragma: no cover - defensive skip
7171
pytest.fail(
7272
f"ParadeDB pg_search extension unavailable in target database: {exc}"
@@ -76,7 +76,7 @@ def paradedb_ready(django_db_setup: object, django_db_blocker: object) -> None:
7676
)
7777
cursor.execute("DROP INDEX IF EXISTS mock_items_bm25_idx;")
7878
cursor.execute(
79-
"CREATE INDEX mock_items_bm25_idx ON mock_items USING bm25 ("
79+
"CREATE INDEX mock_items_bm25_idx ON mock_items USING paradedb ("
8080
"id, "
8181
"description, "
8282
"category, "

tests/test_error_handling.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def test_notices_do_not_raise_exceptions(self) -> None:
9999
with connection.cursor() as cursor:
100100
cursor.execute(
101101
"CREATE INDEX IF NOT EXISTS mock_items_bm25_idx ON mock_items "
102-
"USING bm25 (id, description) WITH (key_field='id');"
102+
"USING paradedb (id, description) WITH (key_field='id');"
103103
)
104104
cursor.execute("SELECT COUNT(*) FROM mock_items;")
105105
(count,) = cursor.fetchone()

0 commit comments

Comments
 (0)