-
Notifications
You must be signed in to change notification settings - Fork 14.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
community/SQLDatabase: Add dedicated documentation page about utility
Up until now, the `SQLDatabase` utility only has been demonstrated on behalf of the "toolkit integration" section, where it is about showcasing an agent designed to interact with an SQL database. [1] Contrary to that, this patch adds a documentation page exclusively dedicated to the SQLDatabase adapter utility, and its features. [1] https://python.langchain.com/docs/integrations/toolkits/sql_database
- Loading branch information
Showing
1 changed file
with
327 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,327 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": { | ||
"collapsed": false | ||
}, | ||
"source": [ | ||
"# SQL Database\n", | ||
"\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", | ||
"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 `result`, `all`, and `one`\n", | ||
"- Bind query parameters\n", | ||
"\n", | ||
"[Chinook Database]: https://github.com/lerocha/chinook-database\n", | ||
"[SQLAlchemy]: https://www.sqlalchemy.org/" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": { | ||
"collapsed": true, | ||
"pycharm": { | ||
"is_executing": 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 | ||
}, | ||
"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 | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"!sqlite3 -bail -cmd '.read Chinook_Sqlite.sql' -cmd '.save Chinook.db' -cmd '.quit'" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": { | ||
"collapsed": false | ||
}, | ||
"source": [ | ||
"## Initialize Database" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 42, | ||
"metadata": { | ||
"collapsed": false | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"from pprint import pprint\n", | ||
"\n", | ||
"import sqlalchemy as sa\n", | ||
"from langchain.sql_database import SQLDatabase\n", | ||
"\n", | ||
"db = SQLDatabase.from_uri(\"sqlite:///Chinook.db\")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": { | ||
"collapsed": false | ||
}, | ||
"source": [ | ||
"## Query as results\n", | ||
"\n", | ||
"The fetch method `result` returns results as SQLAlchemy's\n", | ||
"`CursorResult` instance." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 30, | ||
"metadata": { | ||
"collapsed": 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=\"result\")\n", | ||
"print(type(result))\n", | ||
"pprint(list(result.mappings()))" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": { | ||
"collapsed": false | ||
}, | ||
"source": [ | ||
"## Query as string payload\n", | ||
"\n", | ||
"The fetch methods `all` and `one` return results in string format." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 29, | ||
"metadata": { | ||
"collapsed": 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 | ||
}, | ||
"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 | ||
}, | ||
"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 | ||
}, | ||
"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=\"result\",\n", | ||
")\n", | ||
"pprint(list(result.mappings()))" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": { | ||
"collapsed": 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": 47, | ||
"metadata": { | ||
"collapsed": false | ||
}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"<class 'sqlalchemy.engine.cursor.CursorResult'>\n", | ||
"[{'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=\"result\")\n", | ||
"pprint(list(result.mappings()))" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Python 3", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 2 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython2", | ||
"version": "2.7.6" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 0 | ||
} |