> Google El Carro Oracle Operator 提供了一种在 Kubernetes 中运行 Oracle 数据库的方法,作为一种可移植的开源 社区驱动的、无厂商锁定的容器编排系统。El Carro 提供强大的声明式 API,用于全面且一致的 配置和部署,以及实时操作和 monitoring. 扩展您的 Oracle 数据库功能,构建 AI 驱动的体验 通过利用 El Carro LangChain 集成。
本指南介绍如何使用 El Carro LangChain 集成来 保存、加载和删除 LangChain 文档 与 ElCarroLoader 和 ElCarroDocumentSaver。此集成适用于任何 Oracle 数据库,无论其运行位置如何。
在 GitHub.

准备工作
请完成 中的 入门指南 部分 来设置您的 El Carro Oracle 数据库。
🦜🔗 库安装
该集成位于其自身的 langchain-google-el-carro 包中,因此 我们需要安装它。
pip install -qU langchain-google-el-carro
基本用法
设置 Oracle 数据库连接
使用您的 Oracle 数据库连接详情填充以下变量。
# @title Set Your Values Here { display-mode: "form" }
HOST = "127.0.0.1" # @param {type: "string"}
PORT = 3307 # @param {type: "integer"}
DATABASE = "my-database" # @param {type: "string"}
TABLE_NAME = "message_store" # @param {type: "string"}
USER = "my-user" # @param {type: "string"}
PASSWORD = input("Please provide a password to be used for the database user: ")
如果您使用的是 El Carro,则可以在 El Carro Kubernetes 实例的 状态中找到主机名和端口值。 使用您为 PDB 创建的用户密码。
示例输出:
kubectl get -w instances.oracle.db.anthosapis.com -n db
NAME DB ENGINE VERSION EDITION ENDPOINT URL DB NAMES BACKUP ID READYSTATUS READYREASON DBREADYSTATUS DBREADYREASON
mydb Oracle 18c Express mydb-svc.db 34.71.69.25:6021 ['pdbname'] TRUE CreateComplete True CreateComplete
ElCarroEngine 连接池
ElCarroEngine 配置到 Oracle 数据库的连接池,实现应用程序的成功连接,并遵循行业最佳实践。
from langchain_google_el_carro import ElCarroEngine
elcarro_engine = ElCarroEngine.from_instance(
db_host=HOST,
db_port=PORT,
db_name=DATABASE,
db_user=USER,
db_password=PASSWORD,
)
初始化表
初始化默认模式的表 通过 elcarro_engine.init_document_table(<table_name>)。表列:
- - page_content(类型:text)
- - langchain_metadata(类型:JSON)
elcarro_engine.drop_document_table(TABLE_NAME)
elcarro_engine.init_document_table(
table_name=TABLE_NAME,
)
保存文档
使用以下方式保存 langchain 文档 ElCarroDocumentSaver.add_documents(<documents>). 要初始化 ElCarroDocumentSaver 类,您需要提供 2 个要素:
1. elcarro_engine - 一个 ElCarroEngine engine. 2. table_name 实例 - Oracle 数据库中用于存储的表的名称 LangChain 文档。
from langchain_core.documents import Document
from langchain_google_el_carro import ElCarroDocumentSaver
doc = Document(
page_content="Banana",
metadata={"type": "fruit", "weight": 100, "organic": 1},
)
saver = ElCarroDocumentSaver(
elcarro_engine=elcarro_engine,
table_name=TABLE_NAME,
)
saver.add_documents([doc])
加载文档
使用以下方式加载 LangChain 文档 ElCarroLoader.load() or ElCarroLoader.lazy_load(). lazy_load 返回一个生成器,仅在迭代时查询数据库。 要初始化 ElCarroLoader 类,您需要提供:
1. elcarro_engine - 一个 ElCarroEngine engine. 2. table_name - Oracle 数据库中用于存储的表名 LangChain 文档。
from langchain_google_el_carro import ElCarroLoader
loader = ElCarroLoader(elcarro_engine=elcarro_engine, table_name=TABLE_NAME)
docs = loader.lazy_load()
for doc in docs:
print("Loaded documents:", doc)
通过查询加载文档
除了从表加载文档,我们还可以选择从以下方式加载文档 从 SQL 查询生成的视图加载文档。例如:
from langchain_google_el_carro import ElCarroLoader
loader = ElCarroLoader(
elcarro_engine=elcarro_engine,
query=f"SELECT * FROM {TABLE_NAME} WHERE json_value(langchain_metadata, '$.organic') = '1'",
)
onedoc = loader.load()
print(onedoc)
从 SQL 查询生成的视图可以具有与默认表不同的架构。 在这种情况下,ElCarroLoader 的行为与从表加载相同 使用非默认架构。请参阅 章节 使用自定义文档页面内容和元数据加载文档.
删除文档
从 Oracle 表中删除 LangChain 文档列表 使用 ElCarroDocumentSaver.delete(<documents>).
对于具有默认架构的表(页面_内容,langchain_元数据), 删除条件是:
A row 如果列表中存在 document ,使得
- -
document.page_content等于row[page_content] - -
document.metadata等于row[langchain_metadata]
docs = loader.load()
print("Documents before delete:", docs)
saver.delete(onedoc)
print("Documents after delete:", loader.load())
高级用法
使用自定义文档页面内容和元数据加载文档
首先,我们准备一个具有非默认架构的示例表,并使用 一些任意数据填充它。
create_table_query = f"""CREATE TABLE {TABLE_NAME} (
fruit_id NUMBER GENERATED BY DEFAULT AS IDENTITY (START WITH 1),
fruit_name VARCHAR2(100) NOT NULL,
variety VARCHAR2(50),
quantity_in_stock NUMBER(10) NOT NULL,
price_per_unit NUMBER(6,2) NOT NULL,
organic NUMBER(3) NOT NULL
)"""
elcarro_engine.drop_document_table(TABLE_NAME)
with elcarro_engine.connect() as conn:
conn.execute(sqlalchemy.text(create_table_query))
conn.commit()
conn.execute(
sqlalchemy.text(
f"""
INSERT INTO {TABLE_NAME} (fruit_name, variety, quantity_in_stock, price_per_unit, organic)
VALUES ('Apple', 'Granny Smith', 150, 0.99, 1)
"""
)
)
conn.execute(
sqlalchemy.text(
f"""
INSERT INTO {TABLE_NAME} (fruit_name, variety, quantity_in_stock, price_per_unit, organic)
VALUES ('Banana', 'Cavendish', 200, 0.59, 0)
"""
)
)
conn.execute(
sqlalchemy.text(
f"""
INSERT INTO {TABLE_NAME} (fruit_name, variety, quantity_in_stock, price_per_unit, organic)
VALUES ('Orange', 'Navel', 80, 1.29, 1)
"""
)
)
conn.commit()
如果我们仍然使用默认参数加载 LangChain 文档 ElCarroLoader 从这个示例表中, page_content 加载文档的 将是表的第一列,并且 metadata 将包含所有其他列的键值对 。
loader = ElCarroLoader(
elcarro_engine=elcarro_engine,
table_name=TABLE_NAME,
)
loaded_docs = loader.load()
print(f"Loaded Documents: [{loaded_docs}]")
我们可以通过设置来指定要加载的内容和元数据 和 content_columns 参数 metadata_columns 初始化 时指定 ElCarroLoader.
1. content_columns:要写入 page_content 属性的列 document. 2. metadata_columns:要写入 metadata 属性的列
中的列值 content_columns 将被连接 在一起形成一个以空格分隔的字符串,作为 page_content 加载文档的 ,而 metadata 加载文档的 指定于 metadata_columns.
loader = ElCarroLoader(
elcarro_engine=elcarro_engine,
table_name=TABLE_NAME,
content_columns=[
"variety",
"quantity_in_stock",
"price_per_unit",
"organic",
],
metadata_columns=["fruit_id", "fruit_name"],
)
loaded_docs = loader.load()
print(f"Loaded Documents: [{loaded_docs}]")
保存带有自定义页面内容和元数据的文档
为了将 langchain 文档保存到带有自定义元数据字段的表中 我们需要首先通过以下方式创建这样的表 ElCarroEngine.init_document_table(),以及 指定 metadata_columns 我们希望它拥有的。在本例中, 创建的表将具有以下表列:
- content (类型: text):用于存储水果描述。 - type (类型 VARCHAR2(200)):用于存储水果类型。 - weight (类型 INT):用于存储水果重量。 - extra_json_metadata (类型: JSON):用于存储 fruit.
我们可以使用以下参数 配合 elcarro_engine.init_document_table() 创建表:
1. table_name:Oracle 数据库中用于存储的表名称 langchain 文档。 2. metadata_columns:列表 sqlalchemy.Column 用于指定 我们需要的元数据列。 3. content_column:用于存储 page_content langchain 文档的列名。默认值: "page_content", "VARCHAR2(4000)" 4. metadata_json_column:用于存储额外 JSON metadata langchain 文档的。 Default: "langchain_metadata", "VARCHAR2(4000)".
elcarro_engine.drop_document_table(TABLE_NAME)
elcarro_engine.init_document_table(
table_name=TABLE_NAME,
metadata_columns=[
sqlalchemy.Column("type", sqlalchemy.dialects.oracle.VARCHAR2(200)),
sqlalchemy.Column("weight", sqlalchemy.INT),
],
content_column="content",
metadata_json_column="extra_json_metadata",
)
使用以下方式保存文档 ElCarroDocumentSaver.add_documents(<documents>)。如您 在本示例中可以看到,
- document.page_content 将被保存到 content column. - document.metadata.type 将被保存到 type column. - document.metadata.weight 将被保存到 weight column. - document.metadata.organic 将被保存到 extra_json_metadata 列中 JSON 格式。
doc = Document(
page_content="Banana",
metadata={"type": "fruit", "weight": 100, "organic": 1},
)
print(f"Original Document: [{doc}]")
saver = ElCarroDocumentSaver(
elcarro_engine=elcarro_engine,
table_name=TABLE_NAME,
content_column="content",
metadata_json_column="extra_json_metadata",
)
saver.add_documents([doc])
loader = ElCarroLoader(
elcarro_engine=elcarro_engine,
table_name=TABLE_NAME,
content_columns=["content"],
metadata_columns=[
"type",
"weight",
],
metadata_json_column="extra_json_metadata",
)
loaded_docs = loader.load()
print(f"Loaded Document: [{loaded_docs[0]}]")
删除带有自定义页面内容和元数据的文档
我们也可以通过自定义元数据列从表中删除文档 通过 ElCarroDocumentSaver.delete(<documents>)。删除条件为:
A row 如果列表中存在某个 document ,使得
- document.page_content 等于 row[page_content] - 对于每个元数据字段 k in document.metadata - document.metadata[k] 等于 row[k] or document.metadata[k] 等于 row[langchain_metadata][k] - 中不存在额外的元数据字段 row 但不在 in document.metadata.
loader = ElCarroLoader(elcarro_engine=elcarro_engine, table_name=TABLE_NAME)
saver.delete(loader.load())
print(f"Documents left: {len(loader.load())}")
更多示例
请参阅 at 示例_文档_加载器_basic.py 和 示例_文档_加载器_advanced.py 了解更多 完整代码示例。