Google El Carro for Oracle Workloads
Google El Carro Oracle Operator 提供了一种在 Kubernetes 中运行 Oracle 数据库的方式。它是一个可移植、开源、社区驱动且无供应商锁定锁定的容器编排系统。El Carro 提供了一个强大的声明式 API,用于全面的配置和一致的部署,以及实时操作和监控。 利用 El Carro Langchain 集成,扩展您的 Oracle 数据库功能,构建由 AI 驱动的体验。
本指南将介绍如何使用 El Carro Langchain 集成通过 ElCarroLoader 和 ElCarroDocumentSaver
保存、加载和删除 langchain 文档。此集成适用于任何 Oracle 数据库,无论其运行位置如何。
在此处了解有关该软件包的更多信息:GitHub。
开始之前
请完成 README 中的 入门 部分,以设置您的 El Carro Oracle 数据库。
🦜🔗 库安装
集成位于我们自己的 langchain-google-el-carro 包中,因此我们需要安装它。
%pip install --upgrade --quiet 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 实例的状态中找到主机名(hostname)和端口(port)值。 请使用你为 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>) 初始化一个默认 schema 的表。表字段:
- page_content (类型: text)
- langchain_metadata (类型: JSON)
elcarro_engine.drop_document_table(TABLE_NAME)
elcarro_engine.init_document_table(
table_name=TABLE_NAME,
)
保存文档
使用 ElCarroDocumentSaver.add_documents(<documents>) 保存 langchain 文档。
要初始化 ElCarroDocumentSaver 类,需要提供两样东西:
elcarro_engine-ElCarroEngine引擎的实例。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])
加载文档
使用 ElCarroLoader.load() 或 ElCarroLoader.lazy_load() 加载 Langchain 文档。
lazy_load 返回一个生成器,该生成器仅在迭代期间查询数据库。
要初始化 ElCarroLoader 类,您需要提供:
elcarro_engine-ElCarroEngine引擎的实例。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 查询生成的视图可能具有与默认表不同的 schema。 在这种情况下,ElCarroLoader 的行为与从具有非默认 schema 的表加载相同。请参阅 加载具有自定义文档页面内容和元数据的文档 部分。
删除文档
使用 ElCarroDocumentSaver.delete(<documents>) 从 Oracle 表中删除一组 Langchain 文档。
对于具有默认架构(page_content, langchain_metadata)的表,删除标准是:
如果列表中存在一个 document,则应删除该 row,条件如下:
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())
高级用法
使用自定义文档页面内容和元数据加载文档
首先,我们准备一个具有非默认架构的示例表,并用一些任意数据填充它。
import sqlalchemy
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()
如果我们仍使用下面示例表中 ElCarroLoader 的默认参数加载 LangChain 文档,那么加载文档的 page_content 将是表格的第一列,而 metadata 将由所有其他列的键值对组成。
loader = ElCarroLoader(
elcarro_engine=elcarro_engine,
table_name=TABLE_NAME,
)
loaded_docs = loader.load()
print(f"Loaded Documents: [{loaded_docs}]")
我们可以通过在初始化 ElCarroLoader 时设 置 content_columns 和 metadata_columns 来指定我们想要加载的内容和元数据。
content_columns:要写入文档page_content的列。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):用于存储水果的其他元数据信息。
我们可以使用以下参数与 elcarro_engine.init_document_table() 一起创建表:
table_name:存储 langchain 文档的 Oracle 数据库中的表名。metadata_columns:一个sqlalchemy.Column列表,指示所需的元数据列列表。content_column:用于存储 langchain 文档page_content的列名。默认为"page_content", "VARCHAR2(4000)"metadata_json_column:用于存储 langchain 文档额外 JSONmetadata的列名。 默认为"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列中。document.metadata.type将被保存在type列中。document.metadata.weight将被保存在weight列中。document.metadata.organic将以 JSON 格式保存在extra_json_metadata列中。
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>) 从表中删除具有自定义元数据列的文档。删除标准是:
如果列表中存在一个 document,使得
document.page_content等于row[page_content]- 对于
document.metadata中的每个元数据字段kdocument.metadata[k]等于row[k]或document.metadata[k]等于row[langchain_metadata][k]
row中不存在document.metadata中没有的额外元数据字段。
则应删除该 row。
loader = ElCarroLoader(elcarro_engine=elcarro_engine, table_name=TABLE_NAME)
saver.delete(loader.load())
print(f"Documents left: {len(loader.load())}")
更多示例
请参阅 demo_doc_loader_basic.py 和 demo_doc_loader_advanced.py 了解完整的代码示例。
Related
- Document loader conceptual guide
- Document loader how-to guides