mirror of
https://github.com/langflow-ai/langflow.git
synced 2026-07-24 13:52:34 +08:00
Fix db2 params
This commit is contained in:
@ -48,7 +48,13 @@ class DB2VectorStoreComponent(LCVectorStoreComponent):
|
||||
ModelInput(
|
||||
name="embedding_model",
|
||||
display_name="Embedding Model",
|
||||
info="Select an embedding model provider, or connect an Embeddings component (e.g. watsonx.ai).",
|
||||
info=(
|
||||
"Select an embedding model provider, or connect an Embeddings component (e.g. watsonx.ai). "
|
||||
"Note: with langchain-db2 1.0.0, very high-dimension embeddings (roughly 1,500+ dimensions, "
|
||||
"e.g. OpenAI text-embedding-3-large at 3072) can exceed Db2's VARCHAR bind limit during "
|
||||
"insert. Prefer models around 1,024 dimensions or fewer until a newer langchain-db2 release "
|
||||
"(with the CLOB fix from langchain-ai/langchain-ibm#155) is available."
|
||||
),
|
||||
model_type="embedding",
|
||||
input_types=["Embeddings"],
|
||||
required=True,
|
||||
@ -174,17 +180,6 @@ class DB2VectorStoreComponent(LCVectorStoreComponent):
|
||||
advanced=True,
|
||||
info="Distance calculation strategy",
|
||||
),
|
||||
BoolInput(
|
||||
name="use_bulk_insert",
|
||||
display_name="Use Bulk Insert",
|
||||
value=True,
|
||||
advanced=True,
|
||||
info=(
|
||||
"Enable bulk insert using executemany() for better performance. "
|
||||
"When enabled, all documents are inserted in a single batch (unlimited chunk size). "
|
||||
"When disabled, uses row-by-row insert with execute() (chunk size: 1 document per call)."
|
||||
),
|
||||
),
|
||||
]
|
||||
|
||||
outputs = [
|
||||
@ -417,19 +412,18 @@ class DB2VectorStoreComponent(LCVectorStoreComponent):
|
||||
api_key=getattr(self, "api_key", None),
|
||||
)
|
||||
|
||||
# Log bulk insert mode
|
||||
bulk_insert_enabled = getattr(self, "use_bulk_insert", True)
|
||||
insert_mode = "bulk insert (executemany)" if bulk_insert_enabled else "row-by-row insert (execute)"
|
||||
self.log(f"Insert mode: {insert_mode}")
|
||||
|
||||
# Build vector store (will automatically generate embeddings for existing empty rows)
|
||||
# Build vector store (will automatically generate embeddings for existing empty rows).
|
||||
# NOTE: langchain-db2's DB2VS always bulk-inserts via executemany (add_texts); there is no
|
||||
# toggle for it. add_texts binds the serialized vector as a parameter, so very large
|
||||
# embeddings can exceed Db2's ~32KB VARCHAR limit. The fix (a CLOB cast in
|
||||
# langchain-ai/langchain-ibm#155) is merged upstream but unreleased as of langchain-db2
|
||||
# 1.0.0 — see the Embedding Model input note above.
|
||||
self.log(f"Connecting to DB2 table: {validated_table_name}")
|
||||
vector_store = DB2VS(
|
||||
client=connection,
|
||||
embedding_function=embeddings,
|
||||
table_name=validated_table_name,
|
||||
distance_strategy=distance_strategy_map.get(self.distance_strategy, DistanceStrategy.COSINE),
|
||||
use_bulk_insert=bulk_insert_enabled,
|
||||
)
|
||||
|
||||
self.log(f"Connected to DB2 table: {validated_table_name}")
|
||||
|
||||
@ -832,10 +832,22 @@ class TestDB2VectorStoreComponent:
|
||||
):
|
||||
component._add_documents_to_vector_store(mock_vector_store)
|
||||
|
||||
def test_bulk_insert_enabled_by_default(self, component, mock_embedding):
|
||||
"""Test that bulk insert is enabled by default."""
|
||||
def test_db2vs_constructed_without_use_bulk_insert(self, component, mock_embedding):
|
||||
"""Regression: DB2VS must only receive kwargs the installed langchain-db2 accepts.
|
||||
|
||||
langchain-db2's ``DB2VS`` has no ``use_bulk_insert`` parameter (it always bulk-inserts
|
||||
via ``executemany``), so passing it would raise ``TypeError`` at runtime. Because the
|
||||
other tests mock ``DB2VS.__init__`` (which hides such signature mismatches), assert here
|
||||
that the kwargs the component passes are a subset of the real ``DB2VS.__init__`` signature.
|
||||
"""
|
||||
import inspect
|
||||
|
||||
component.embedding_model = mock_embedding
|
||||
|
||||
from langchain_db2 import DB2VS
|
||||
|
||||
supported_params = set(inspect.signature(DB2VS.__init__).parameters) - {"self"}
|
||||
|
||||
with (
|
||||
patch("ibm_db_dbi.connect") as mock_connect,
|
||||
patch.object(component, "_add_documents_to_vector_store"),
|
||||
@ -843,141 +855,16 @@ class TestDB2VectorStoreComponent:
|
||||
mock_connection = MagicMock()
|
||||
mock_connect.return_value = mock_connection
|
||||
|
||||
from langchain_db2 import DB2VS
|
||||
|
||||
with patch.object(DB2VS, "__init__", return_value=None) as mock_init:
|
||||
component.build_vector_store()
|
||||
|
||||
# Verify use_bulk_insert was passed as True (default)
|
||||
call_kwargs = mock_init.call_args[1]
|
||||
assert call_kwargs["use_bulk_insert"] is True
|
||||
|
||||
def test_bulk_insert_toggle_enabled(self, component, mock_embedding):
|
||||
"""Test bulk insert when explicitly enabled."""
|
||||
component.embedding_model = mock_embedding
|
||||
component.use_bulk_insert = True
|
||||
|
||||
with (
|
||||
patch("ibm_db_dbi.connect") as mock_connect,
|
||||
patch.object(component, "_add_documents_to_vector_store"),
|
||||
):
|
||||
mock_connection = MagicMock()
|
||||
mock_connect.return_value = mock_connection
|
||||
|
||||
from langchain_db2 import DB2VS
|
||||
|
||||
with patch.object(DB2VS, "__init__", return_value=None) as mock_init:
|
||||
component.build_vector_store()
|
||||
|
||||
# Verify use_bulk_insert was passed as True
|
||||
call_kwargs = mock_init.call_args[1]
|
||||
assert call_kwargs["use_bulk_insert"] is True
|
||||
|
||||
def test_bulk_insert_toggle_disabled(self, component, mock_embedding):
|
||||
"""Test bulk insert when explicitly disabled."""
|
||||
component.embedding_model = mock_embedding
|
||||
component.use_bulk_insert = False
|
||||
|
||||
with (
|
||||
patch("ibm_db_dbi.connect") as mock_connect,
|
||||
patch.object(component, "_add_documents_to_vector_store"),
|
||||
):
|
||||
mock_connection = MagicMock()
|
||||
mock_connect.return_value = mock_connection
|
||||
|
||||
from langchain_db2 import DB2VS
|
||||
|
||||
with patch.object(DB2VS, "__init__", return_value=None) as mock_init:
|
||||
component.build_vector_store()
|
||||
|
||||
# Verify use_bulk_insert was passed as False
|
||||
call_kwargs = mock_init.call_args[1]
|
||||
assert call_kwargs["use_bulk_insert"] is False
|
||||
|
||||
def test_bulk_insert_with_multiple_documents(self, component, mock_embedding):
|
||||
"""Test bulk insert with multiple documents."""
|
||||
component.embedding_model = mock_embedding
|
||||
component.use_bulk_insert = True
|
||||
component.ingest_data = [
|
||||
Data(text="Document 1"),
|
||||
Data(text="Document 2"),
|
||||
Data(text="Document 3"),
|
||||
Data(text="Document 4"),
|
||||
Data(text="Document 5"),
|
||||
]
|
||||
|
||||
with (
|
||||
patch("ibm_db_dbi.connect") as mock_connect,
|
||||
):
|
||||
mock_connection = MagicMock()
|
||||
mock_cursor = MagicMock()
|
||||
mock_connection.cursor.return_value = mock_cursor
|
||||
mock_connect.return_value = mock_connection
|
||||
|
||||
from langchain_db2 import DB2VS
|
||||
|
||||
with (
|
||||
patch.object(DB2VS, "__init__", return_value=None),
|
||||
patch.object(DB2VS, "add_documents") as mock_add_docs,
|
||||
):
|
||||
vector_store = component.build_vector_store()
|
||||
component._add_documents_to_vector_store(vector_store)
|
||||
|
||||
# Verify documents were added
|
||||
if mock_add_docs.called:
|
||||
added_docs = mock_add_docs.call_args[0][0]
|
||||
assert len(added_docs) == 5, "All 5 documents should be added"
|
||||
|
||||
def test_bulk_insert_logging(self, component, mock_embedding):
|
||||
"""Test that bulk insert mode is logged correctly."""
|
||||
component.embedding_model = mock_embedding
|
||||
component.use_bulk_insert = True
|
||||
|
||||
with (
|
||||
patch("ibm_db_dbi.connect") as mock_connect,
|
||||
patch.object(component, "_add_documents_to_vector_store"),
|
||||
):
|
||||
mock_connection = MagicMock()
|
||||
mock_connect.return_value = mock_connection
|
||||
|
||||
from langchain_db2 import DB2VS
|
||||
|
||||
with patch.object(DB2VS, "__init__", return_value=None), patch.object(component, "log") as mock_log:
|
||||
component.build_vector_store()
|
||||
|
||||
messages = [str(call.args[0]).lower() for call in mock_log.call_args_list]
|
||||
assert any("bulk insert" in message or "executemany" in message for message in messages)
|
||||
|
||||
def test_row_by_row_insert_logging(self, component, mock_embedding):
|
||||
"""Test that row-by-row insert mode is logged correctly."""
|
||||
component.embedding_model = mock_embedding
|
||||
component.use_bulk_insert = False
|
||||
|
||||
with (
|
||||
patch("ibm_db_dbi.connect") as mock_connect,
|
||||
patch.object(component, "_add_documents_to_vector_store"),
|
||||
):
|
||||
mock_connection = MagicMock()
|
||||
mock_connect.return_value = mock_connection
|
||||
|
||||
from langchain_db2 import DB2VS
|
||||
|
||||
with patch.object(DB2VS, "__init__", return_value=None), patch.object(component, "log") as mock_log:
|
||||
component.build_vector_store()
|
||||
|
||||
messages = [str(call.args[0]).lower() for call in mock_log.call_args_list]
|
||||
assert any("row-by-row" in message or "execute" in message for message in messages)
|
||||
|
||||
def test_bulk_insert_input_exists(self, component):
|
||||
"""Test that use_bulk_insert input is defined in component."""
|
||||
# Check that the input exists in the component's inputs
|
||||
input_names = [inp.name for inp in component.inputs]
|
||||
assert "use_bulk_insert" in input_names, "use_bulk_insert input should be defined"
|
||||
|
||||
# Find the input and verify its properties
|
||||
bulk_insert_input = next(inp for inp in component.inputs if inp.name == "use_bulk_insert")
|
||||
assert bulk_insert_input.value is True, "Default value should be True"
|
||||
assert bulk_insert_input.advanced is True, "Should be an advanced setting"
|
||||
passed_kwargs = set(mock_init.call_args.kwargs)
|
||||
assert "use_bulk_insert" not in passed_kwargs, (
|
||||
"DB2VS no longer accepts `use_bulk_insert`; do not pass it to the constructor."
|
||||
)
|
||||
assert passed_kwargs <= supported_params, (
|
||||
f"DB2VS called with unsupported kwargs: {sorted(passed_kwargs - supported_params)}"
|
||||
)
|
||||
|
||||
|
||||
# Made with Bob
|
||||
|
||||
Reference in New Issue
Block a user