mirror of
https://github.com/hwchase17/langchain.git
synced 2026-02-21 14:43:07 +00:00
414 lines
10 KiB
Plaintext
414 lines
10 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"collapsed": false,
|
|
"jupyter": {
|
|
"outputs_hidden": false
|
|
}
|
|
},
|
|
"source": [
|
|
"# SQL Database\n",
|
|
"\n",
|
|
"::: {.callout-note}\n",
|
|
"The `SQLDatabase` adapter utility is a wrapper around a database connection.\n",
|
|
"\n",
|
|
"For talking to SQL databases, it uses the [SQLAlchemy] Core API .\n",
|
|
":::\n",
|
|
"\n",
|
|
"\n",
|
|
"This notebook shows how to use the utility to access an SQLite database.\n",
|
|
"It uses the example [Chinook Database], and demonstrates those features:\n",
|
|
"\n",
|
|
"- Query using SQL\n",
|
|
"- Query using SQLAlchemy selectable\n",
|
|
"- Fetch modes `cursor`, `all`, and `one`\n",
|
|
"- Bind query parameters\n",
|
|
"\n",
|
|
"[Chinook Database]: https://github.com/lerocha/chinook-database\n",
|
|
"[SQLAlchemy]: https://www.sqlalchemy.org/\n",
|
|
"\n",
|
|
"\n",
|
|
"You can use the `Tool` or `@tool` decorator to create a tool from this utility.\n",
|
|
"\n",
|
|
"\n",
|
|
"::: {.callout-caution}\n",
|
|
"If creating a tool from the SQLDatbase utility and combining it with an LLM or exposing it to an end user\n",
|
|
"remember to follow good security practices.\n",
|
|
"\n",
|
|
"See security information: https://python.langchain.com/docs/security\n",
|
|
":::"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"collapsed": true,
|
|
"jupyter": {
|
|
"outputs_hidden": true
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"!wget 'https://github.com/lerocha/chinook-database/releases/download/v1.4.2/Chinook_Sqlite.sql'"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 22,
|
|
"metadata": {
|
|
"collapsed": false,
|
|
"jupyter": {
|
|
"outputs_hidden": false
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"1|AC/DC\r\n",
|
|
"2|Accept\r\n",
|
|
"3|Aerosmith\r\n",
|
|
"4|Alanis Morissette\r\n",
|
|
"5|Alice In Chains\r\n",
|
|
"6|Antônio Carlos Jobim\r\n",
|
|
"7|Apocalyptica\r\n",
|
|
"8|Audioslave\r\n",
|
|
"9|BackBeat\r\n",
|
|
"10|Billy Cobham\r\n",
|
|
"11|Black Label Society\r\n",
|
|
"12|Black Sabbath\r\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"!sqlite3 -bail -cmd '.read Chinook_Sqlite.sql' -cmd 'SELECT * FROM Artist LIMIT 12;' -cmd '.quit'"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 12,
|
|
"metadata": {
|
|
"collapsed": false,
|
|
"jupyter": {
|
|
"outputs_hidden": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"!sqlite3 -bail -cmd '.read Chinook_Sqlite.sql' -cmd '.save Chinook.db' -cmd '.quit'"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"collapsed": false,
|
|
"jupyter": {
|
|
"outputs_hidden": false
|
|
}
|
|
},
|
|
"source": [
|
|
"## Initialize Database"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {
|
|
"collapsed": false,
|
|
"jupyter": {
|
|
"outputs_hidden": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"from pprint import pprint\n",
|
|
"\n",
|
|
"import sqlalchemy as sa\n",
|
|
"from langchain_community.utilities import SQLDatabase\n",
|
|
"\n",
|
|
"db = SQLDatabase.from_uri(\"sqlite:///Chinook.db\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"collapsed": false,
|
|
"jupyter": {
|
|
"outputs_hidden": false
|
|
}
|
|
},
|
|
"source": [
|
|
"## Query as cursor\n",
|
|
"\n",
|
|
"The fetch mode `cursor` returns results as SQLAlchemy's\n",
|
|
"`CursorResult` instance."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 30,
|
|
"metadata": {
|
|
"collapsed": false,
|
|
"jupyter": {
|
|
"outputs_hidden": false
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"<class 'sqlalchemy.engine.cursor.CursorResult'>\n",
|
|
"[{'ArtistId': 1, 'Name': 'AC/DC'},\n",
|
|
" {'ArtistId': 2, 'Name': 'Accept'},\n",
|
|
" {'ArtistId': 3, 'Name': 'Aerosmith'},\n",
|
|
" {'ArtistId': 4, 'Name': 'Alanis Morissette'},\n",
|
|
" {'ArtistId': 5, 'Name': 'Alice In Chains'},\n",
|
|
" {'ArtistId': 6, 'Name': 'Antônio Carlos Jobim'},\n",
|
|
" {'ArtistId': 7, 'Name': 'Apocalyptica'},\n",
|
|
" {'ArtistId': 8, 'Name': 'Audioslave'},\n",
|
|
" {'ArtistId': 9, 'Name': 'BackBeat'},\n",
|
|
" {'ArtistId': 10, 'Name': 'Billy Cobham'},\n",
|
|
" {'ArtistId': 11, 'Name': 'Black Label Society'},\n",
|
|
" {'ArtistId': 12, 'Name': 'Black Sabbath'}]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"result = db.run(\"SELECT * FROM Artist LIMIT 12;\", fetch=\"cursor\")\n",
|
|
"print(type(result))\n",
|
|
"pprint(list(result.mappings()))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"collapsed": false,
|
|
"jupyter": {
|
|
"outputs_hidden": false
|
|
}
|
|
},
|
|
"source": [
|
|
"## Query as string payload\n",
|
|
"\n",
|
|
"The fetch modes `all` and `one` return results in string format."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 29,
|
|
"metadata": {
|
|
"collapsed": false,
|
|
"jupyter": {
|
|
"outputs_hidden": false
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"<class 'str'>\n",
|
|
"[(1, 'AC/DC'), (2, 'Accept'), (3, 'Aerosmith'), (4, 'Alanis Morissette'), (5, 'Alice In Chains'), (6, 'Antônio Carlos Jobim'), (7, 'Apocalyptica'), (8, 'Audioslave'), (9, 'BackBeat'), (10, 'Billy Cobham'), (11, 'Black Label Society'), (12, 'Black Sabbath')]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"result = db.run(\"SELECT * FROM Artist LIMIT 12;\", fetch=\"all\")\n",
|
|
"print(type(result))\n",
|
|
"print(result)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 31,
|
|
"metadata": {
|
|
"collapsed": false,
|
|
"jupyter": {
|
|
"outputs_hidden": false
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"<class 'str'>\n",
|
|
"[(1, 'AC/DC')]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"result = db.run(\"SELECT * FROM Artist LIMIT 12;\", fetch=\"one\")\n",
|
|
"print(type(result))\n",
|
|
"print(result)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"collapsed": false,
|
|
"jupyter": {
|
|
"outputs_hidden": false
|
|
}
|
|
},
|
|
"source": [
|
|
"## Query with parameters\n",
|
|
"\n",
|
|
"In order to bind query parameters, use the optional `parameters` argument."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 41,
|
|
"metadata": {
|
|
"collapsed": false,
|
|
"jupyter": {
|
|
"outputs_hidden": false
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"[{'ArtistId': 35, 'Name': 'Pedro Luís & A Parede'},\n",
|
|
" {'ArtistId': 115, 'Name': 'Page & Plant'},\n",
|
|
" {'ArtistId': 116, 'Name': 'Passengers'},\n",
|
|
" {'ArtistId': 117, 'Name': \"Paul D'Ianno\"},\n",
|
|
" {'ArtistId': 118, 'Name': 'Pearl Jam'},\n",
|
|
" {'ArtistId': 119, 'Name': 'Peter Tosh'},\n",
|
|
" {'ArtistId': 120, 'Name': 'Pink Floyd'},\n",
|
|
" {'ArtistId': 121, 'Name': 'Planet Hemp'},\n",
|
|
" {'ArtistId': 186, 'Name': 'Pedro Luís E A Parede'},\n",
|
|
" {'ArtistId': 256, 'Name': 'Philharmonia Orchestra & Sir Neville Marriner'},\n",
|
|
" {'ArtistId': 275, 'Name': 'Philip Glass Ensemble'}]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"result = db.run(\n",
|
|
" \"SELECT * FROM Artist WHERE Name LIKE :search;\",\n",
|
|
" parameters={\"search\": \"p%\"},\n",
|
|
" fetch=\"cursor\",\n",
|
|
")\n",
|
|
"pprint(list(result.mappings()))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"collapsed": false,
|
|
"jupyter": {
|
|
"outputs_hidden": false
|
|
}
|
|
},
|
|
"source": [
|
|
"## Query with SQLAlchemy selectable\n",
|
|
"\n",
|
|
"Other than plain-text SQL statements, the adapter also accepts SQLAlchemy selectables."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {
|
|
"collapsed": false,
|
|
"jupyter": {
|
|
"outputs_hidden": false
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"[{'ArtistId': 35, 'Name': 'Pedro Luís & A Parede'},\n",
|
|
" {'ArtistId': 115, 'Name': 'Page & Plant'},\n",
|
|
" {'ArtistId': 116, 'Name': 'Passengers'},\n",
|
|
" {'ArtistId': 117, 'Name': \"Paul D'Ianno\"},\n",
|
|
" {'ArtistId': 118, 'Name': 'Pearl Jam'},\n",
|
|
" {'ArtistId': 119, 'Name': 'Peter Tosh'},\n",
|
|
" {'ArtistId': 120, 'Name': 'Pink Floyd'},\n",
|
|
" {'ArtistId': 121, 'Name': 'Planet Hemp'},\n",
|
|
" {'ArtistId': 186, 'Name': 'Pedro Luís E A Parede'},\n",
|
|
" {'ArtistId': 256, 'Name': 'Philharmonia Orchestra & Sir Neville Marriner'},\n",
|
|
" {'ArtistId': 275, 'Name': 'Philip Glass Ensemble'}]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# In order to build a selectable on SA's Core API, you need a table definition.\n",
|
|
"metadata = sa.MetaData()\n",
|
|
"artist = sa.Table(\n",
|
|
" \"Artist\",\n",
|
|
" metadata,\n",
|
|
" sa.Column(\"ArtistId\", sa.INTEGER, primary_key=True),\n",
|
|
" sa.Column(\"Name\", sa.TEXT),\n",
|
|
")\n",
|
|
"\n",
|
|
"# Build a selectable with the same semantics of the recent query.\n",
|
|
"query = sa.select(artist).where(artist.c.Name.like(\"p%\"))\n",
|
|
"result = db.run(query, fetch=\"cursor\")\n",
|
|
"pprint(list(result.mappings()))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"collapsed": false,
|
|
"jupyter": {
|
|
"outputs_hidden": false
|
|
}
|
|
},
|
|
"source": [
|
|
"## Query with execution options\n",
|
|
"\n",
|
|
"It is possible to augment the statement invocation with custom execution options.\n",
|
|
"For example, when applying a schema name translation, subsequent statements will\n",
|
|
"fail, because they try to hit a non-existing table."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"collapsed": false,
|
|
"jupyter": {
|
|
"outputs_hidden": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"query = sa.select(artist).where(artist.c.Name.like(\"p%\"))\n",
|
|
"db.run(query, fetch=\"cursor\", execution_options={\"schema_translate_map\": {None: \"bar\"}})"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python 3 (ipykernel)",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.10.12"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 4
|
|
}
|