Binary fields default to attachment storage in Odoo 19, but FAISS embedding vectors need to be loaded in bulk via direct SQL for performance. Using attachment=False stores them in the table column. Made-with: Cursor
49 lines
1.6 KiB
Python
49 lines
1.6 KiB
Python
import logging
|
|
import pickle
|
|
|
|
from odoo import api, models, fields
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
class EncoachTrainingTip(models.Model):
|
|
_name = "encoach.training.tip"
|
|
_description = "EnCoach Training Tip"
|
|
|
|
tip_id = fields.Char(required=True, index=True)
|
|
category = fields.Selection(
|
|
[
|
|
("ct_focus", "CT Focus"),
|
|
("language_for_writing", "Language for Writing"),
|
|
("reading_skill", "Reading Skill"),
|
|
("strategy", "Strategy"),
|
|
("writing_skill", "Writing Skill"),
|
|
("word_link", "Word Link"),
|
|
("word_partners", "Word Partners"),
|
|
],
|
|
string="Category",
|
|
)
|
|
content = fields.Text(required=True)
|
|
embedding = fields.Binary(string="FAISS Embedding Vector", attachment=False)
|
|
|
|
def action_compute_embeddings(self):
|
|
"""Compute sentence-transformer embeddings for tips missing them."""
|
|
try:
|
|
from sentence_transformers import SentenceTransformer
|
|
import numpy as np
|
|
except ImportError:
|
|
_logger.error("sentence-transformers not installed; cannot compute embeddings")
|
|
return
|
|
|
|
tips = self.search([("embedding", "=", False)])
|
|
if not tips:
|
|
_logger.info("All tips already have embeddings")
|
|
return
|
|
|
|
model = SentenceTransformer("all-MiniLM-L6-v2")
|
|
for tip in tips:
|
|
vec = model.encode([tip.content]).astype(np.float32)[0]
|
|
tip.embedding = pickle.dumps(vec)
|
|
|
|
_logger.info("Computed embeddings for %d tips", len(tips))
|