mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-11-01 04:25:44 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
34be974edc |
No files matched your search
+5
-5
@@ -10334,18 +10334,18 @@
|
|||||||
<context context-type="linenumber">294,295</context>
|
<context context-type="linenumber">294,295</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="3420321797707163677" datatype="html">
|
<trans-unit id="2179847500064178686" datatype="html">
|
||||||
<source>Preview document</source>
|
<source>Edit document</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
|
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
|
||||||
<context context-type="linenumber">328</context>
|
<context context-type="linenumber">328</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="2179847500064178686" datatype="html">
|
<trans-unit id="3420321797707163677" datatype="html">
|
||||||
<source>Edit document</source>
|
<source>Preview document</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
|
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
|
||||||
<context context-type="linenumber">331</context>
|
<context context-type="linenumber">329</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4512084577073831437" datatype="html">
|
<trans-unit id="4512084577073831437" datatype="html">
|
||||||
|
|||||||
+7
@@ -1,3 +1,10 @@
|
|||||||
.custom-fields-dropdown {
|
.custom-fields-dropdown {
|
||||||
min-width: 300px;
|
min-width: 300px;
|
||||||
|
|
||||||
|
// correct position on mobile
|
||||||
|
@media (max-width: 575.98px) {
|
||||||
|
&.show {
|
||||||
|
margin-left: -245px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -308,7 +308,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr class="align-middle">
|
<tr class="align-middle">
|
||||||
<td i18n>Original SHA256 checksum</td>
|
<td i18n>Original SHA256 checksum</td>
|
||||||
<td><span class="badge bg-light text-dark font-monospace text-wrap text-break text-start">{{metadata()?.original_checksum}}</span></td>
|
<td><span class="badge bg-light font-monospace text-wrap text-break text-start">{{metadata()?.original_checksum}}</span></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td i18n>Original file size</td>
|
<td i18n>Original file size</td>
|
||||||
@@ -465,7 +465,7 @@
|
|||||||
@switch (archiveContentRenderType) {
|
@switch (archiveContentRenderType) {
|
||||||
@case (ContentRenderType.PDF) {
|
@case (ContentRenderType.PDF) {
|
||||||
@if (!useNativePdfViewer) {
|
@if (!useNativePdfViewer) {
|
||||||
<div class="preview-sticky pdf-viewer-container" tabindex="-1">
|
<div class="preview-sticky pdf-viewer-container">
|
||||||
<pngx-pdf-viewer
|
<pngx-pdf-viewer
|
||||||
[src]="pdfSource()"
|
[src]="pdfSource()"
|
||||||
[sourceRevision]="previewRevision()"
|
[sourceRevision]="previewRevision()"
|
||||||
@@ -477,7 +477,7 @@
|
|||||||
(loadError)="onError($event)"
|
(loadError)="onError($event)"
|
||||||
(afterLoadComplete)="pdfPreviewLoaded($event)">
|
(afterLoadComplete)="pdfPreviewLoaded($event)">
|
||||||
</pngx-pdf-viewer>
|
</pngx-pdf-viewer>
|
||||||
<div class="preview-controls position-absolute bottom-0 start-50 translate-middle-x z-1 mb-3 d-flex gap-2 p-1 bg-body border rounded shadow">
|
<div class="position-absolute bottom-0 start-50 translate-middle-x z-1 mb-3 d-flex gap-2 p-1 bg-body border rounded shadow">
|
||||||
@if (previewNumPages()) {
|
@if (previewNumPages()) {
|
||||||
<div class="input-group input-group-sm w-auto flex-nowrap">
|
<div class="input-group input-group-sm w-auto flex-nowrap">
|
||||||
<input class="form-control flex-grow-0 w-auto" type="number" min="1" [max]="previewNumPages()" [ngModelOptions]="{standalone: true}" [ngModel]="previewCurrentPage()" (ngModelChange)="previewCurrentPage.set($event)" aria-label="Page" i18n-aria-label />
|
<input class="form-control flex-grow-0 w-auto" type="number" min="1" [max]="previewNumPages()" [ngModelOptions]="{standalone: true}" [ngModel]="previewCurrentPage()" (ngModelChange)="previewCurrentPage.set($event)" aria-label="Page" i18n-aria-label />
|
||||||
|
|||||||
@@ -12,22 +12,6 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:focus {
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-controls {
|
|
||||||
opacity: 0;
|
|
||||||
pointer-events: none;
|
|
||||||
transition: opacity 0.15s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover .preview-controls,
|
|
||||||
&:focus-within .preview-controls {
|
|
||||||
opacity: 1;
|
|
||||||
pointer-events: auto;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-group .dropdown-toggle-split {
|
.btn-group .dropdown-toggle-split {
|
||||||
|
|||||||
@@ -208,7 +208,7 @@
|
|||||||
i18n>Correspondent</th>
|
i18n>Correspondent</th>
|
||||||
}
|
}
|
||||||
@if (activeDisplayFields.includes(DisplayField.TITLE)) {
|
@if (activeDisplayFields.includes(DisplayField.TITLE)) {
|
||||||
<th class="cursor-pointer ps-5"
|
<th class="cursor-pointer"
|
||||||
pngxSortable="title"
|
pngxSortable="title"
|
||||||
title="Sort by title" i18n-title
|
title="Sort by title" i18n-title
|
||||||
[currentSortField]="list.sortField"
|
[currentSortField]="list.sortField"
|
||||||
@@ -322,13 +322,13 @@
|
|||||||
</td>
|
</td>
|
||||||
}
|
}
|
||||||
@if (activeDisplayFields.includes(DisplayField.TITLE) || activeDisplayFields.includes(DisplayField.TAGS)) {
|
@if (activeDisplayFields.includes(DisplayField.TITLE) || activeDisplayFields.includes(DisplayField.TAGS)) {
|
||||||
<td width="30%" class="position-relative" [class.ps-5]="activeDisplayFields.includes(DisplayField.TITLE)">
|
<td width="30%">
|
||||||
@if (activeDisplayFields.includes(DisplayField.TITLE)) {
|
@if (activeDisplayFields.includes(DisplayField.TITLE)) {
|
||||||
<div class="d-inline-block" (mouseleave)="popupPreview.close()">
|
<div class="d-inline-block" (mouseleave)="popupPreview.close()">
|
||||||
<pngx-preview-popup class="position-absolute start-0" [document]="d" linkClasses="btn btn-sm btn-link text-secondary" linkTitle="Preview document" (click)="$event.stopPropagation()" i18n-linkTitle #popupPreview>
|
<a routerLink="/documents/{{d.id}}" title="Edit document" i18n-title style="overflow-wrap: anywhere;">{{d.title | documentTitle}}</a>
|
||||||
|
<pngx-preview-popup [document]="d" linkClasses="btn btn-sm btn-link text-secondary" linkTitle="Preview document" (click)="$event.stopPropagation()" i18n-linkTitle #popupPreview>
|
||||||
<i-bs name="eye"></i-bs>
|
<i-bs name="eye"></i-bs>
|
||||||
</pngx-preview-popup>
|
</pngx-preview-popup>
|
||||||
<a routerLink="/documents/{{d.id}}" title="Edit document" i18n-title style="overflow-wrap: anywhere;">{{d.title | documentTitle}}</a>
|
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (activeDisplayFields.includes(DisplayField.TAGS)) {
|
@if (activeDisplayFields.includes(DisplayField.TAGS)) {
|
||||||
|
|||||||
@@ -87,10 +87,6 @@ $paperless-card-breakpoints: (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.table .ps-5 {
|
|
||||||
padding-left: 2.2rem !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
a {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -291,12 +291,19 @@ def get_permission_grantees(
|
|||||||
"permission__codename__in": list(action_by_codename),
|
"permission__codename__in": list(action_by_codename),
|
||||||
"object_pk__in": [str(pk) for pk in pks],
|
"object_pk__in": [str(pk) for pk in pks],
|
||||||
}
|
}
|
||||||
for perm_model, identity_field, key in (
|
for perm_model, identity_model, identity_field, key in (
|
||||||
(UserObjectPermission, "user_id", "users"),
|
(UserObjectPermission, User, "user_id", "users"),
|
||||||
(GroupObjectPermission, "group_id", "groups"),
|
(GroupObjectPermission, Group, "group_id", "groups"),
|
||||||
):
|
):
|
||||||
|
# Every grant belongs to an existing user or group, so restricting to
|
||||||
|
# them changes no result. It lets MariaDB use guardian's
|
||||||
|
# (identity, content_type, object_pk) index; the content type alone
|
||||||
|
# matches every grant of the model and is scanned in full.
|
||||||
rows = (
|
rows = (
|
||||||
perm_model.objects.filter(**grant_filter)
|
perm_model.objects.filter(
|
||||||
|
**{f"{identity_field}__in": identity_model.objects.values("pk")},
|
||||||
|
**grant_filter,
|
||||||
|
)
|
||||||
.values_list("object_pk", "permission__codename", identity_field)
|
.values_list("object_pk", "permission__codename", identity_field)
|
||||||
.order_by(identity_field)
|
.order_by(identity_field)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -397,10 +397,14 @@ class OwnedObjectSerializer(
|
|||||||
object_pks = list(obj.pk for obj in objects)
|
object_pks = list(obj.pk for obj in objects)
|
||||||
pk_type = type(first_obj.pk)
|
pk_type = type(first_obj.pk)
|
||||||
|
|
||||||
def get_pks_for_permission_type(model):
|
def get_pks_for_permission_type(model, identity_field, identity_model):
|
||||||
|
# Restricting to existing users/groups changes no result but lets
|
||||||
|
# MariaDB use guardian's (identity, content_type, object_pk) index
|
||||||
|
# instead of scanning every grant of the model.
|
||||||
return map(
|
return map(
|
||||||
pk_type, # coerce the pk to be the same type of the provided objects
|
pk_type, # coerce the pk to be the same type of the provided objects
|
||||||
model.objects.filter(
|
model.objects.filter(
|
||||||
|
**{f"{identity_field}__in": identity_model.objects.values("pk")},
|
||||||
content_type=ctype,
|
content_type=ctype,
|
||||||
object_pk__in=object_pks,
|
object_pk__in=object_pks,
|
||||||
)
|
)
|
||||||
@@ -410,8 +414,16 @@ class OwnedObjectSerializer(
|
|||||||
|
|
||||||
UserObjectPermission = get_user_obj_perms_model()
|
UserObjectPermission = get_user_obj_perms_model()
|
||||||
GroupObjectPermission = get_group_obj_perms_model()
|
GroupObjectPermission = get_group_obj_perms_model()
|
||||||
user_permission_pks = get_pks_for_permission_type(UserObjectPermission)
|
user_permission_pks = get_pks_for_permission_type(
|
||||||
group_permission_pks = get_pks_for_permission_type(GroupObjectPermission)
|
UserObjectPermission,
|
||||||
|
"user_id",
|
||||||
|
User,
|
||||||
|
)
|
||||||
|
group_permission_pks = get_pks_for_permission_type(
|
||||||
|
GroupObjectPermission,
|
||||||
|
"group_id",
|
||||||
|
Group,
|
||||||
|
)
|
||||||
|
|
||||||
return set(user_permission_pks) | set(group_permission_pks)
|
return set(user_permission_pks) | set(group_permission_pks)
|
||||||
|
|
||||||
|
|||||||
@@ -1,93 +0,0 @@
|
|||||||
import sqlite3
|
|
||||||
from collections.abc import Generator
|
|
||||||
from pathlib import Path
|
|
||||||
from unittest.mock import patch
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
from llama_index.core.schema import TextNode
|
|
||||||
|
|
||||||
from paperless_ai.tables import DocumentChunksTable
|
|
||||||
from paperless_ai.vector_store import DB_FILENAME
|
|
||||||
from paperless_ai.vector_store import DEFAULT_TABLE_NAME
|
|
||||||
from paperless_ai.vector_store import VEC0_CHUNK_SIZE
|
|
||||||
from paperless_ai.vector_store import PaperlessSqliteVecVectorStore
|
|
||||||
|
|
||||||
DIM = 16
|
|
||||||
|
|
||||||
|
|
||||||
def make_node(node_id: str, document_id: int) -> TextNode:
|
|
||||||
node = TextNode(
|
|
||||||
id_=node_id,
|
|
||||||
text="some text",
|
|
||||||
metadata={"document_id": document_id, "modified": "2026-06-10T00:00:00"},
|
|
||||||
)
|
|
||||||
node.relationships = {}
|
|
||||||
node.embedding = [document_id + i / 100 for i in range(DIM)]
|
|
||||||
return node
|
|
||||||
|
|
||||||
|
|
||||||
def vec_table_sql(db_path: Path) -> str:
|
|
||||||
conn = sqlite3.connect(db_path)
|
|
||||||
try:
|
|
||||||
return conn.execute(
|
|
||||||
"SELECT sql FROM sqlite_master WHERE name = ?",
|
|
||||||
(DEFAULT_TABLE_NAME,),
|
|
||||||
).fetchone()[0]
|
|
||||||
finally:
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
|
|
||||||
def create_legacy_vec_table(conn: sqlite3.Connection, dim: int) -> None:
|
|
||||||
"""The table definition from before chunk_size was set explicitly."""
|
|
||||||
conn.execute(
|
|
||||||
f"CREATE VIRTUAL TABLE {DEFAULT_TABLE_NAME} USING vec0("
|
|
||||||
"id TEXT PRIMARY KEY, document_id INTEGER, +node_content TEXT, "
|
|
||||||
f"embedding float[{dim}] distance_metric=cosine)",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def store(tmp_path: Path) -> Generator[PaperlessSqliteVecVectorStore, None, None]:
|
|
||||||
with PaperlessSqliteVecVectorStore(uri=str(tmp_path)) as store:
|
|
||||||
yield store
|
|
||||||
|
|
||||||
|
|
||||||
class TestVecChunkSize:
|
|
||||||
def test_new_table_uses_configured_chunk_size(
|
|
||||||
self,
|
|
||||||
store: PaperlessSqliteVecVectorStore,
|
|
||||||
tmp_path: Path,
|
|
||||||
) -> None:
|
|
||||||
"""
|
|
||||||
GIVEN an empty store
|
|
||||||
WHEN the first document is indexed and the vec0 table is created
|
|
||||||
THEN the table definition carries the configured chunk size
|
|
||||||
"""
|
|
||||||
store.upsert_document(1, [make_node("1-a", 1)])
|
|
||||||
|
|
||||||
assert f"chunk_size={VEC0_CHUNK_SIZE}" in vec_table_sql(tmp_path / DB_FILENAME)
|
|
||||||
|
|
||||||
def test_compact_moves_legacy_table_to_configured_chunk_size(
|
|
||||||
self,
|
|
||||||
store: PaperlessSqliteVecVectorStore,
|
|
||||||
tmp_path: Path,
|
|
||||||
) -> None:
|
|
||||||
"""
|
|
||||||
GIVEN an index whose vec0 table was created with the default chunk size
|
|
||||||
WHEN the index is compacted
|
|
||||||
THEN the rebuilt table uses the configured chunk size
|
|
||||||
AND no indexed chunks are lost
|
|
||||||
"""
|
|
||||||
with patch.object(
|
|
||||||
PaperlessSqliteVecVectorStore,
|
|
||||||
"_create_vec_table",
|
|
||||||
staticmethod(create_legacy_vec_table),
|
|
||||||
):
|
|
||||||
store.upsert_document(1, [make_node("1-a", 1), make_node("1-b", 1)])
|
|
||||||
store.upsert_document(2, [make_node("2-a", 2)])
|
|
||||||
assert "chunk_size" not in vec_table_sql(tmp_path / DB_FILENAME)
|
|
||||||
|
|
||||||
store.compact(force=True)
|
|
||||||
|
|
||||||
assert f"chunk_size={VEC0_CHUNK_SIZE}" in vec_table_sql(tmp_path / DB_FILENAME)
|
|
||||||
assert DocumentChunksTable.count(store.client) == 3
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
import sqlite3
|
|
||||||
from collections.abc import Generator
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
from llama_index.core.schema import TextNode
|
|
||||||
|
|
||||||
from paperless_ai.tables import DocumentChunksTable
|
|
||||||
from paperless_ai.vector_store import DB_FILENAME
|
|
||||||
from paperless_ai.vector_store import DB_PAGE_SIZE
|
|
||||||
from paperless_ai.vector_store import PaperlessSqliteVecVectorStore
|
|
||||||
|
|
||||||
DIM = 16
|
|
||||||
LEGACY_PAGE_SIZE = 4096
|
|
||||||
|
|
||||||
|
|
||||||
def make_node(node_id: str, document_id: int) -> TextNode:
|
|
||||||
node = TextNode(
|
|
||||||
id_=node_id,
|
|
||||||
text="some text",
|
|
||||||
metadata={"document_id": document_id, "modified": "2026-06-10T00:00:00"},
|
|
||||||
)
|
|
||||||
node.relationships = {}
|
|
||||||
node.embedding = [document_id + i / 100 for i in range(DIM)]
|
|
||||||
return node
|
|
||||||
|
|
||||||
|
|
||||||
def page_size_of(db_path: Path) -> int:
|
|
||||||
conn = sqlite3.connect(db_path)
|
|
||||||
try:
|
|
||||||
return conn.execute("PRAGMA page_size").fetchone()[0]
|
|
||||||
finally:
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def legacy_page_size_db(tmp_path: Path) -> Path:
|
|
||||||
"""An existing index file created before the page size was set."""
|
|
||||||
db_path = tmp_path / DB_FILENAME
|
|
||||||
conn = sqlite3.connect(db_path)
|
|
||||||
conn.execute(f"PRAGMA page_size={LEGACY_PAGE_SIZE}")
|
|
||||||
conn.execute("CREATE TABLE _seed(x)")
|
|
||||||
conn.execute("DROP TABLE _seed")
|
|
||||||
conn.close()
|
|
||||||
assert page_size_of(db_path) == LEGACY_PAGE_SIZE
|
|
||||||
return db_path
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def store(tmp_path: Path) -> Generator[PaperlessSqliteVecVectorStore, None, None]:
|
|
||||||
with PaperlessSqliteVecVectorStore(uri=str(tmp_path)) as store:
|
|
||||||
yield store
|
|
||||||
|
|
||||||
|
|
||||||
class TestIndexPageSize:
|
|
||||||
def test_new_index_file_uses_configured_page_size(
|
|
||||||
self,
|
|
||||||
store: PaperlessSqliteVecVectorStore,
|
|
||||||
tmp_path: Path,
|
|
||||||
) -> None:
|
|
||||||
"""
|
|
||||||
GIVEN no existing index file
|
|
||||||
WHEN a store is opened and a document is indexed
|
|
||||||
THEN the database file uses the configured page size
|
|
||||||
"""
|
|
||||||
store.upsert_document(1, [make_node("1-a", 1)])
|
|
||||||
|
|
||||||
assert page_size_of(tmp_path / DB_FILENAME) == DB_PAGE_SIZE
|
|
||||||
|
|
||||||
def test_compact_moves_legacy_file_to_configured_page_size(
|
|
||||||
self,
|
|
||||||
legacy_page_size_db: Path,
|
|
||||||
) -> None:
|
|
||||||
"""
|
|
||||||
GIVEN an existing index file created with a different page size
|
|
||||||
WHEN the index is compacted
|
|
||||||
THEN the rebuilt file uses the configured page size
|
|
||||||
AND no indexed chunks are lost
|
|
||||||
"""
|
|
||||||
with PaperlessSqliteVecVectorStore(
|
|
||||||
uri=str(legacy_page_size_db.parent),
|
|
||||||
) as store:
|
|
||||||
store.upsert_document(1, [make_node("1-a", 1), make_node("1-b", 1)])
|
|
||||||
assert page_size_of(legacy_page_size_db) == LEGACY_PAGE_SIZE
|
|
||||||
|
|
||||||
store.compact(force=True)
|
|
||||||
|
|
||||||
assert page_size_of(legacy_page_size_db) == DB_PAGE_SIZE
|
|
||||||
assert DocumentChunksTable.count(store.client) == 2
|
|
||||||
@@ -47,20 +47,6 @@ SCHEMA_VERSION = 2
|
|||||||
# a rebuild copies the live rows into a fresh table.
|
# a rebuild copies the live rows into a fresh table.
|
||||||
COMPACT_BLOAT_RATIO = 2.0
|
COMPACT_BLOAT_RATIO = 2.0
|
||||||
|
|
||||||
# Rows per vec0 vector chunk (vec0's default is 1024, which makes each chunk a
|
|
||||||
# multi-megabyte blob). On spinning disks, inserts and re-indexing were dozens
|
|
||||||
# of times faster with small chunks, at no cost in query speed or file size.
|
|
||||||
# Only applies to tables created from here on; an existing index picks it up
|
|
||||||
# the next time it is rebuilt (compact or rebuild).
|
|
||||||
VEC0_CHUNK_SIZE = 32
|
|
||||||
|
|
||||||
# SQLite page size for the index file, in bytes. With the small vec0 chunks above,
|
|
||||||
# 64 KiB pages made cold scans about 35% faster and warm ones about 45% faster,
|
|
||||||
# at the cost of a larger write-ahead log (up to about 70 MB). Only takes effect
|
|
||||||
# on a newly created file, so like the chunk size it reaches an existing index
|
|
||||||
# when it is rebuilt.
|
|
||||||
DB_PAGE_SIZE = 65536
|
|
||||||
|
|
||||||
# Number of rows fetched/copied per batch whenever this module streams rows
|
# Number of rows fetched/copied per batch whenever this module streams rows
|
||||||
# instead of materializing them all at once, keeping memory bounded regardless
|
# instead of materializing them all at once, keeping memory bounded regardless
|
||||||
# of index size -- used by compact()'s rebuild, m0001_v1_to_v2's migration
|
# of index size -- used by compact()'s rebuild, m0001_v1_to_v2's migration
|
||||||
@@ -236,7 +222,6 @@ class PaperlessSqliteVecVectorStore(BasePydanticVectorStore):
|
|||||||
conn.enable_load_extension(True) # noqa: FBT003
|
conn.enable_load_extension(True) # noqa: FBT003
|
||||||
sqlite_vec.load(conn)
|
sqlite_vec.load(conn)
|
||||||
conn.enable_load_extension(False) # noqa: FBT003
|
conn.enable_load_extension(False) # noqa: FBT003
|
||||||
conn.execute(f"PRAGMA page_size={DB_PAGE_SIZE}")
|
|
||||||
conn.execute("PRAGMA journal_mode=WAL")
|
conn.execute("PRAGMA journal_mode=WAL")
|
||||||
conn.execute("PRAGMA synchronous=NORMAL")
|
conn.execute("PRAGMA synchronous=NORMAL")
|
||||||
IndexMetaTable.create(conn)
|
IndexMetaTable.create(conn)
|
||||||
@@ -344,8 +329,7 @@ class PaperlessSqliteVecVectorStore(BasePydanticVectorStore):
|
|||||||
+ " +node_content TEXT,"
|
+ " +node_content TEXT,"
|
||||||
+ " embedding float["
|
+ " embedding float["
|
||||||
+ str(int(dim))
|
+ str(int(dim))
|
||||||
+ "] distance_metric=cosine, chunk_size="
|
+ "] distance_metric=cosine"
|
||||||
+ str(VEC0_CHUNK_SIZE)
|
|
||||||
+ ")",
|
+ ")",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user