mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-07-22 23:31:12 +02:00
feat: refine source_markdown migration logic to only convert documents with blocknote_document data, ensuring lazy population for others
This commit is contained in:
parent
8b497da130
commit
e1087937e6
2 changed files with 33 additions and 1429 deletions
|
|
@ -4,14 +4,12 @@ Revision ID: 101
|
||||||
Revises: 100
|
Revises: 100
|
||||||
Create Date: 2026-02-17
|
Create Date: 2026-02-17
|
||||||
|
|
||||||
Adds source_markdown column and populates it for existing documents
|
Adds source_markdown column and converts only documents that have
|
||||||
using a pure-Python BlockNote JSON → Markdown converter. No external
|
blocknote_document data. Uses a pure-Python BlockNote JSON → Markdown
|
||||||
dependencies (no Node.js, no Celery, no HTTP calls).
|
converter. No external dependencies (no Node.js, no Celery, no HTTP calls).
|
||||||
|
|
||||||
Fallback chain per document:
|
Documents without blocknote_document keep source_markdown = NULL and
|
||||||
1. blocknote_document exists → convert to markdown with Python converter
|
get populated lazily by the editor route when a user first opens them.
|
||||||
2. blocknote_document missing/fails → reconstruct from chunks
|
|
||||||
3. Neither exists → skip (log warning)
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
@ -48,103 +46,67 @@ def upgrade() -> None:
|
||||||
sa.Column("source_markdown", sa.Text(), nullable=True),
|
sa.Column("source_markdown", sa.Text(), nullable=True),
|
||||||
)
|
)
|
||||||
|
|
||||||
# 2. Populate source_markdown for existing documents (inline, synchronous)
|
# 2. Convert only documents that have blocknote_document data
|
||||||
_populate_source_markdown(conn)
|
_populate_source_markdown(conn)
|
||||||
|
|
||||||
|
|
||||||
def _populate_source_markdown(conn) -> None:
|
def _populate_source_markdown(conn) -> None:
|
||||||
"""Populate source_markdown for all documents where it is NULL.
|
"""Populate source_markdown only for documents that have blocknote_document."""
|
||||||
|
|
||||||
Fallback chain:
|
|
||||||
1. blocknote_document → pure-Python converter → source_markdown
|
|
||||||
2. chunks (ordered by id) → joined text → source_markdown
|
|
||||||
3. Neither → skip with warning
|
|
||||||
"""
|
|
||||||
# Import the pure-Python converter (no external deps)
|
|
||||||
from app.utils.blocknote_to_markdown import blocknote_to_markdown
|
from app.utils.blocknote_to_markdown import blocknote_to_markdown
|
||||||
|
|
||||||
# Find documents that need migration
|
# Only fetch documents that have blocknote_document content
|
||||||
result = conn.execute(
|
result = conn.execute(
|
||||||
sa.text("""
|
sa.text("""
|
||||||
SELECT id, title, blocknote_document
|
SELECT id, title, blocknote_document
|
||||||
FROM documents
|
FROM documents
|
||||||
WHERE source_markdown IS NULL
|
WHERE source_markdown IS NULL
|
||||||
|
AND blocknote_document IS NOT NULL
|
||||||
""")
|
""")
|
||||||
)
|
)
|
||||||
rows = result.fetchall()
|
rows = result.fetchall()
|
||||||
|
|
||||||
total = len(rows)
|
total = len(rows)
|
||||||
if total == 0:
|
if total == 0:
|
||||||
print("✓ No documents need source_markdown migration")
|
print("✓ No documents with blocknote_document need migration")
|
||||||
return
|
return
|
||||||
|
|
||||||
print(f" Migrating {total} documents to source_markdown...")
|
print(f" Migrating {total} documents (with blocknote_document) to source_markdown...")
|
||||||
|
|
||||||
migrated = 0
|
migrated = 0
|
||||||
from_blocknote = 0
|
failed = 0
|
||||||
from_chunks = 0
|
|
||||||
skipped = 0
|
|
||||||
|
|
||||||
for row in rows:
|
for row in rows:
|
||||||
doc_id = row[0]
|
doc_id = row[0]
|
||||||
doc_title = row[1]
|
doc_title = row[1]
|
||||||
blocknote_doc = row[2]
|
blocknote_doc = row[2]
|
||||||
|
|
||||||
markdown = None
|
try:
|
||||||
|
if isinstance(blocknote_doc, str):
|
||||||
|
blocknote_doc = json.loads(blocknote_doc)
|
||||||
|
markdown = blocknote_to_markdown(blocknote_doc)
|
||||||
|
|
||||||
# --- Fallback 1: Convert blocknote_document with pure Python ---
|
if markdown:
|
||||||
if blocknote_doc:
|
conn.execute(
|
||||||
try:
|
sa.text("""
|
||||||
# blocknote_doc may be a JSON string or already parsed
|
UPDATE documents SET source_markdown = :md WHERE id = :doc_id
|
||||||
if isinstance(blocknote_doc, str):
|
"""),
|
||||||
blocknote_doc = json.loads(blocknote_doc)
|
{"md": markdown, "doc_id": doc_id},
|
||||||
markdown = blocknote_to_markdown(blocknote_doc)
|
|
||||||
if markdown:
|
|
||||||
from_blocknote += 1
|
|
||||||
except Exception as e:
|
|
||||||
logger.warning(
|
|
||||||
f" Doc {doc_id} ({doc_title}): blocknote conversion failed ({e}), "
|
|
||||||
f"falling back to chunks"
|
|
||||||
)
|
)
|
||||||
|
migrated += 1
|
||||||
# --- Fallback 2: Reconstruct from chunks ---
|
else:
|
||||||
if not markdown:
|
logger.warning(
|
||||||
chunk_result = conn.execute(
|
f" Doc {doc_id} ({doc_title}): blocknote conversion produced empty result"
|
||||||
sa.text("""
|
)
|
||||||
SELECT content FROM chunks
|
failed += 1
|
||||||
WHERE document_id = :doc_id
|
except Exception as e:
|
||||||
ORDER BY id
|
|
||||||
"""),
|
|
||||||
{"doc_id": doc_id},
|
|
||||||
)
|
|
||||||
chunk_rows = chunk_result.fetchall()
|
|
||||||
if chunk_rows:
|
|
||||||
chunk_texts = [r[0] for r in chunk_rows if r[0]]
|
|
||||||
if chunk_texts:
|
|
||||||
markdown = "\n\n".join(chunk_texts)
|
|
||||||
from_chunks += 1
|
|
||||||
|
|
||||||
# --- Fallback 3: Nothing to migrate from ---
|
|
||||||
if not markdown or not markdown.strip():
|
|
||||||
logger.warning(
|
logger.warning(
|
||||||
f" Doc {doc_id} ({doc_title}): no blocknote_document or chunks — skipped"
|
f" Doc {doc_id} ({doc_title}): blocknote conversion failed ({e})"
|
||||||
)
|
)
|
||||||
skipped += 1
|
failed += 1
|
||||||
continue
|
|
||||||
|
|
||||||
# Write source_markdown
|
|
||||||
conn.execute(
|
|
||||||
sa.text("""
|
|
||||||
UPDATE documents SET source_markdown = :md WHERE id = :doc_id
|
|
||||||
"""),
|
|
||||||
{"md": markdown, "doc_id": doc_id},
|
|
||||||
)
|
|
||||||
migrated += 1
|
|
||||||
|
|
||||||
print(
|
print(
|
||||||
f"✓ source_markdown migration complete: {migrated} migrated "
|
f"✓ source_markdown migration complete: {migrated} migrated, "
|
||||||
f"({from_blocknote} from blocknote, {from_chunks} from chunks), "
|
f"{failed} failed out of {total} total"
|
||||||
f"{skipped} skipped out of {total} total"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
1358
surfsense_web/pnpm-lock.yaml
generated
1358
surfsense_web/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue