### Development Setup Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Commands to set up the development environment for Bendsql Python bindings. This includes navigating to the test directory, starting services, and installing dependencies. ```shell cd tests make up ``` ```shell cd bindings/python uv python install 3.12 uv venv --python 3.12 uv sync --extra local source .venv/bin/activate maturin develop ``` ```shell behave tests/asyncio behave tests/blocking behave tests/cursor behave tests/local ``` -------------------------------- ### Start Frontend Development Server Source: https://github.com/databendlabs/bendsql/blob/main/agents/frontend.md Run this command to start the interactive development server for the frontend. Ensure you have two terminals open: one for the frontend and one for the CLI. ```bash cd frontend && pnpm run dev ``` -------------------------------- ### Install BendSQL using cargo-binstall Source: https://github.com/databendlabs/bendsql/blob/main/README.md Installs BendSQL using the cargo-binstall tool for efficient binary installation. ```bash cargo binstall bendsql ``` -------------------------------- ### Start BendSQL UI Interface Source: https://github.com/databendlabs/bendsql/blob/main/cli/README.md Launch BendSQL with the UI interface enabled, specifying host and port. ```sh ❯ bendsql -h localhost --port 8000 --ui ``` -------------------------------- ### BendSQL REPL Usage Example Source: https://github.com/databendlabs/bendsql/blob/main/cli/README.md Demonstrates interactive usage of the BendSQL REPL, including executing a query and showing tables. ```sql ❯ bendsql Welcome to BendSQL. Connecting to localhost:8000 as user root. Connected to Databend Query bendsql> select avg(number) from numbers(10); select avg(number) from numbers(10) ╭───────────────────────────────────────────────────────╮ │ sum(number) / if(count(number) = 0, 1, count(number)) │ │ Nullable(Float64) │ ├───────────────────────────────────────────────────────┤ │ 4.5 │ ╰───────────────────────────────────────────────────────╯ 1 row read in 0.032 sec. Processed 10 row, 80 B (312.5 rows/s, 2.44 KiB/s) bendsql> show tables like 'd%'; show tables like 'd%' ┌───────────────────┐ │ tables_in_default │ │ String │ ├───────────────────┤ │ data │ │ data2 │ │ data3 │ │ data4 │ └───────────────────┘ 4 rows in 0.106 sec. Processed 0 rows, 0B (0 rows/s, 0B/s) bendsql> exit Bye~ ``` -------------------------------- ### Example Bendsql Configuration File Source: https://github.com/databendlabs/bendsql/blob/main/README.md This TOML file shows the structure for custom connection and settings configurations. ```toml [connection] host = "127.0.0.1" tls = false [connection.args] connect_timeout = "30" [settings] display_pretty_sql = true progress_color = "green" no_auto_complete = true prompt = ":) " ``` -------------------------------- ### Install BendSQL using Cargo Source: https://github.com/databendlabs/bendsql/blob/main/cli/README.md Install the BendSQL CLI tool using the Cargo package manager. ```sh cargo install bendsql ``` -------------------------------- ### DSN Example with Flight Protocol and Connection Timeout Source: https://github.com/databendlabs/bendsql/blob/main/README.md Demonstrates a DSN using the Flight protocol, specifying a root user, host, port, database, and a custom connection timeout. ```text databend+flight://root:@localhost:8900/database1?connect_timeout=10 ``` -------------------------------- ### DSN Example with SSL Disabled and Presign Argument Source: https://github.com/databendlabs/bendsql/blob/main/README.md Illustrates a DSN format for connecting to a Databend instance, specifying SSL mode and presign behavior. ```text databend://root:@localhost:8000/?sslmode=disable&presign=detect ``` -------------------------------- ### Configure Apt repository for BendSQL (old format) Source: https://github.com/databendlabs/bendsql/blob/main/README.md Sets up the older APT repository format for installing BendSQL on older Ubuntu/Debian versions. ```bash sudo curl -L -o /usr/share/keyrings/databend-keyring.gpg https://repo.databend.com/deb/databend.gpg sudo curl -L -o /etc/apt/sources.list.d/databend.list https://repo.databend.com/deb/databend.list ``` -------------------------------- ### Update and install BendSQL via Apt Source: https://github.com/databendlabs/bendsql/blob/main/README.md Updates the package list and installs BendSQL after configuring the Apt repository. ```bash sudo apt update sudo apt install bendsql ``` -------------------------------- ### Install BendSQL using Homebrew Source: https://github.com/databendlabs/bendsql/blob/main/README.md Installs BendSQL on macOS or Linux using the Homebrew package manager. ```bash brew install databendcloud/homebrew-tap/bendsql ``` -------------------------------- ### Install BendSQL using curl script Source: https://github.com/databendlabs/bendsql/blob/main/README.md Installs BendSQL using a curl script. The second variant allows specifying an installation prefix. ```bash curl -fsSL https://repo.databend.com/install/bendsql.sh | bash ``` ```bash curl -fsSL https://repo.databend.com/install/bendsql.sh | bash -s -- -y --prefix /usr/local ``` -------------------------------- ### Configure Apt repository for BendSQL (DEB822 format) Source: https://github.com/databendlabs/bendsql/blob/main/README.md Sets up the DEB822-style APT repository for installing BendSQL on newer Ubuntu/Debian versions. ```bash sudo curl -L -o /etc/apt/sources.list.d/databend.sources https://repo.databend.com/deb/databend.sources ``` -------------------------------- ### Install Databend Driver with Local Extra Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Install the databend-driver package with the 'local' extra to enable the local embedded engine. This requires Python 3.12 or later. ```bash pip install "databend-driver[local]" ``` -------------------------------- ### DSN Example with Authentication and Warehouse Source: https://github.com/databendlabs/bendsql/blob/main/README.md Shows a DSN for connecting to a Databend Cloud instance, including user credentials, host, port, database, and specific cloud arguments. ```text databend://user1:password1@tnxxxx.gw.aws-us-east-2.default.databend.com:443/benchmark?warehouse=default&enable_dphyp=1 ``` -------------------------------- ### Insert VARIANT data Source: https://github.com/databendlabs/bendsql/blob/main/driver/README.md Example of creating a table with a VARIANT column and inserting JSON data. ```sql CREATE TABLE example ( data VARIANT ); INSERT INTO example VALUES ('{"a": 1, "b": "hello"}'); ``` -------------------------------- ### Parameter Binding in Databend Node.js Client Source: https://github.com/databendlabs/bendsql/blob/main/bindings/nodejs/README.md Provides examples of parameter binding for queries using positional, named, and placeholder syntax with the Databend Node.js client. ```javascript const row = await this.conn.queryRow( "SELECT $1, $2, $3, $4", (params = [3, false, 4, "55"]), ); ``` ```javascript const row = await this.conn.queryRow( "SELECT :a, :b, :c, :d", (params = { a: 3, b: false, c: 4, d: "55" }), ); ``` ```javascript const row = await this.conn.queryRow("SELECT ?, ?, ?, ?", [3, false, 4, "55"]); ``` -------------------------------- ### Query VARIANT data in Rust Source: https://github.com/databendlabs/bendsql/blob/main/driver/README.md Example of querying a VARIANT column in Rust and deserializing the JSON string into a serde_json::Value. ```rust let row = conn.query_row("SELECT * FROM example LIMIT 1").await.unwrap(); let (data,): (String,) = row.unwrap().try_into().unwrap(); let value: serde_json::Value = serde_json::from_str(&data).unwrap(); println!("{:?}", value); ``` -------------------------------- ### Query ID Tracking and Management Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Shows how to retrieve the last executed query ID, get the ID of a newly executed query, and how to kill a running query. ```python # Get the last executed query ID query_id = conn.last_query_id() print(f"Last query ID: {query_id}") ``` ```python # Execute a query and get its ID await conn.query_row("SELECT 1") query_id = conn.last_query_id() print(f"Query ID: {query_id}") ``` ```python # Kill a running query (if needed) try: await conn.kill_query("some-query-id") print("Query killed successfully") except Exception as e: print(f"Failed to kill query: {e}") ``` -------------------------------- ### Asyncio Connection and Query Execution Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Demonstrates how to establish an asynchronous connection to Databend, create a table, and iterate over query results using asyncio. ```python import asyncio from databend_driver import AsyncDatabendClient async def main(): client = AsyncDatabendClient('databend://root:root@localhost:8000/?sslmode=disable') conn = await client.get_conn() await conn.exec( """ CREATE TABLE test ( i64 Int64, u64 UInt64, f64 Float64, s String, s2 String, d Date, t DateTime ) """ ) rows = await conn.query_iter("SELECT * FROM test") async for row in rows: print(row.values()) await conn.close() asyncio.run(main()) ``` -------------------------------- ### Connect and Execute Queries with Databend Node.js Client Source: https://github.com/databendlabs/bendsql/blob/main/bindings/nodejs/README.md Demonstrates how to establish a connection, create a table, and execute queries using the Databend Node.js client. Shows different methods for fetching query results. ```javascript const { Client } = require("databend-driver"); const client = new Client( "databend://root:root@localhost:8000/?sslmode=disable", ); const conn = await client.getConn(); await conn.exec(`CREATE TABLE test ( i64 Int64, u64 UInt64, f64 Float64, s String, s2 String, d Date, t DateTime );`); // get rows of value array const rows = await conn.queryIter("SELECT * FROM test"); let row = await rows.next(); while (row) { console.log(row.values()); row = await rows.next(); } // get rows of map const rows = await conn.queryIter("SELECT * FROM test"); let row = await rows.next(); while (row) { console.log(row.data()); row = await rows.next(); } // iter rows const rows = await conn.queryIter("SELECT * FROM test"); for await (const row of rows) { console.log(row.values()); } // pipe rows import { Transform } from "node:stream"; import { finished, pipeline } from "node:stream/promises"; const rows = await conn.queryIter("SELECT * FROM test"); const stream = rows.stream(); const transformer = new Transform({ readableObjectMode: true, writableObjectMode: true, transform(row, _, callback) { console.log(row.data()); }, }); await pipeline(stream, transformer); await finished(stream); await conn.close(); ``` -------------------------------- ### Build and Test Databend Node.js Client Source: https://github.com/databendlabs/bendsql/blob/main/bindings/nodejs/README.md Instructions for setting up the development environment, building the debug version, and running tests for the Databend Node.js client. ```shell cd bindings/nodejs pnpm install pnpm run build:debug pnpm run test ``` -------------------------------- ### Connect and Execute Basic SQL Source: https://github.com/databendlabs/bendsql/blob/main/driver/README.md Establishes a connection to Databend and executes CREATE TABLE and INSERT statements. ```rust use databend_driver::Client; let dsn = "databend://root:@localhost:8000/default?sslmode=disable".to_string(); let client = Client::new(dsn); let conn = client.get_conn().await.unwrap(); // Execute DDL let sql_create = "CREATE TABLE books ( title VARCHAR, author VARCHAR, date Date );"; conn.exec(sql_create).await.unwrap(); // Execute DML let sql_insert = "INSERT INTO books VALUES ('The Little Prince', 'Antoine de Saint-Exupéry', '1943-04-06');"; conn.exec(sql_insert).await.unwrap(); conn.close().await ``` -------------------------------- ### Build Frontend for Validation Source: https://github.com/databendlabs/bendsql/blob/main/agents/frontend.md Run this command to build the frontend as a minimum validation step after making changes to the frontend code. ```bash cd frontend && pnpm run build ``` -------------------------------- ### BendSQL Help Command Source: https://github.com/databendlabs/bendsql/blob/main/cli/README.md Display the help information for the BendSQL CLI, showing available options and usage. ```sh ❯ bendsql --help ``` -------------------------------- ### Run Integration Tests Source: https://github.com/databendlabs/bendsql/blob/main/README.md Execute `make integration` to run integration tests. Docker and Docker Compose are required. ```bash make integration ``` -------------------------------- ### Set Configuration in Bendsql REPL Source: https://github.com/databendlabs/bendsql/blob/main/README.md Demonstrates how to dynamically update settings like display format and row limits within the Bendsql interactive session. ```bash ❯ bendsql :) !set display_pretty_sql false :) !set max_display_rows 10 :) !set expand auto ``` -------------------------------- ### Stage Local Files Source: https://github.com/databendlabs/bendsql/blob/main/cli/README.md Commands to create a stage and put local files into it. ```sql create stage s_temp; put fs:///tmp/a*.txt @s_temp/abc; ``` -------------------------------- ### Build Frontend Production Assets Source: https://github.com/databendlabs/bendsql/blob/main/agents/frontend.md Execute this command to rebuild the frontend assets for production. This is part of the overall build process. ```bash make build-frontend ``` -------------------------------- ### Parameter Binding Styles Source: https://github.com/databendlabs/bendsql/blob/main/driver/README.md Demonstrates different methods for binding parameters to SQL queries, including positional, named, and placeholder styles. ```rust // Positional parameters (PostgreSQL style) let row = conn.query("SELECT $1, $2, $3, $4") .bind((3, false, 4, "55")) .one() .await.unwrap(); // Named parameters let params = params! {a => 3, b => false, c => 4, d => "55"}; let row = conn.query("SELECT :a, :b, :c, :d") .bind(params) .one() .await.unwrap(); // Question mark placeholders let row = conn.query("SELECT ?, ?, ?, ?") .bind((3, false, 4, "55")) .one() .await.unwrap(); // Insert with parameters conn.exec("INSERT INTO books VALUES (?, ?, ?)") .bind(("New Book", "Author Name", "2024-01-01")) .await.unwrap() ``` -------------------------------- ### AsyncDatabendClient Initialization Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Shows the basic initialization of the `AsyncDatabendClient` with a Data Source Name (DSN) string. ```python class AsyncDatabendClient: def __init__(self, dsn: str): ... async def get_conn(self) -> AsyncDatabendConnection: ... ``` -------------------------------- ### Build and Run CLI with Frontend Assets Source: https://github.com/databendlabs/bendsql/blob/main/agents/frontend.md These commands will rebuild frontend assets before building or running the CLI, ensuring the latest frontend code is included. ```bash make build ``` ```bash make run ``` -------------------------------- ### Handle GEOMETRY/GEOGRAPHY Output Formats Source: https://github.com/databendlabs/bendsql/blob/main/bindings/nodejs/README.md Illustrates how to handle GEOMETRY and GEOGRAPHY data types based on the `geometry_output_format` setting. Shows how to check if the output is a Buffer. ```javascript const row = await conn.queryRow( "settings(geometry_output_format='WKB') SELECT st_point(60, 37)", ); console.log(Buffer.isBuffer(row.values()[0])); ``` -------------------------------- ### Run Unit Tests with Cargo Source: https://github.com/databendlabs/bendsql/blob/main/README.md Execute `make test` to run the project's unit tests. ```bash make test ``` -------------------------------- ### Parameter Binding in Queries Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Illustrates different methods for binding parameters to SQL queries, including positional (?), named (:name), and keyword argument forms. ```python # Positional parameters using ? row = await context.conn.query_row("SELECT ?, ?, ?, ?", (3, False, 4, "55")) ``` ```python # Named parameters using :name row = await context.conn.query_row( "SELECT :a, :b, :c, :d", {"a": 3, "b": False, "c": 4, "d": "55"} ) ``` ```python # Single value (no tuple needed) row = await context.conn.query_row("SELECT ?", 3) ``` ```python # Keyword argument form row = await context.conn.query_row("SELECT ?, ?, ?, ?", params=(3, False, 4, "55")) ``` -------------------------------- ### BlockingDatabendClient Initialization Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Initializes a blocking client for Databend. Use this when synchronous database operations are required. ```python class BlockingDatabendClient: def __init__(self, dsn: str): ... def get_conn(self) -> BlockingDatabendConnection: ... def cursor(self) -> BlockingDatabendCursor: ... ``` -------------------------------- ### Builder Pattern for Query Construction Source: https://github.com/databendlabs/bendsql/blob/main/driver/README.md Illustrates using the Builder pattern for constructing queries, including conditional parameter binding and different execution modes. ```rust // Simple execution conn.exec("CREATE TABLE test (id INT)").await?; // Conditional parameter binding let mut query = conn.query("SELECT * FROM books"); if let Some(author_filter) = author_name { query = query.bind(params![author_filter]); } let books = query.all().await?; // Different execution modes let single_book = conn.query("SELECT * FROM books LIMIT 1").one().await?; let all_books = conn.query("SELECT * FROM books").all().await?; let book_stream = conn.query("SELECT * FROM books").iter().await?; let book_stats = conn.query("SELECT COUNT(*)").iter_ext().await?; ``` -------------------------------- ### Run Code Checks with Cargo Source: https://github.com/databendlabs/bendsql/blob/main/README.md Execute `make check` to run cargo fmt, clippy, and deny for code quality checks. ```bash make check ``` -------------------------------- ### connect_local Function Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Establishes a connection to a local Databend instance. Allows specifying the database, data path, and tenant. ```python def connect_local( database: str = ":memory:", *, data_path: str | None = None, tenant: str | None = None, ) -> LocalConnection: ... ``` -------------------------------- ### Migrate Databend Driver API calls Source: https://github.com/databendlabs/bendsql/blob/main/driver/README.md Compares the old API for executing queries and inserting data with the new Builder API and direct methods. The Builder API is recommended for new development. ```rust // Old API conn.exec("INSERT INTO test VALUES (?)", params![1]).await?; conn.query_all("SELECT * FROM test WHERE id = ?", params![1]).await?; // New Builder API (recommended) conn.exec("INSERT INTO test VALUES (?)").bind(params![1]).await?; conn.query("SELECT * FROM test WHERE id = ?").bind(params![1]).all().await?; // Or use direct methods (compatible) conn.query_all("SELECT * FROM test").await?; ``` -------------------------------- ### Connect to Remote Databend Instance Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Connect to a remote Databend server using a standard DSN. Ensure the server is accessible and connection parameters are correct. ```python from databend_driver import connect conn = connect("databend://root:@localhost:8000/?sslmode=disable") row = conn.query_row("SELECT 1") ``` -------------------------------- ### Run Rust TCP Test Container with Docker Source: https://github.com/databendlabs/bendsql/blob/main/ttc/README.md This command runs the Rust TCP Test Container using Docker. It maps the host's network and specifies the port and Databend DSN for connection. ```bash docker run --net host ghcr.io/databendlabs/ttc-rust -P 9092 --databend_dsn databend://default:@127.0.0.1:8000 ``` -------------------------------- ### ConnectionInfo Object Properties Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Holds information about the database connection, including handler, host, port, user, and database/warehouse details. ```python class ConnectionInfo: @property def handler(self) -> str: ... @property def host(self) -> str: ... @property def port(self) -> int: ... @property def user(self) -> str: ... @property def database(self) -> str | None: ... @property def warehouse(self) -> str | None: ... ``` -------------------------------- ### ORM Support for Typed Objects Source: https://github.com/databendlabs/bendsql/blob/main/driver/README.md Shows how to map query results to Rust structs and insert typed objects using the ORM features. ```rust use databend_driver::serde_bend; #[derive(serde_bend, Debug)] struct Book { title: String, author: String, #[serde_bend(rename = "publication_date")] date: chrono::NaiveDate, } // Query as typed objects let cursor = conn.query_as::("SELECT * FROM books WHERE author = ?") .bind(params!["Antoine de Saint-Exupéry"]) .await?; let books = cursor.fetch_all().await?; for book in books { println!("{:?}", book); } // Insert typed objects let mut insert = conn.insert::("books").await?; insert.write(&Book { title: "New Book".to_string(), author: "New Author".to_string(), date: chrono::NaiveDate::from_ymd_opt(2024, 1, 1).unwrap(), }).await?; let inserted = insert.end().await?; ``` -------------------------------- ### Validate CLI Serving and Proxy Behavior Source: https://github.com/databendlabs/bendsql/blob/main/agents/frontend.md If UI serving or proxy behavior has been modified, use this command to validate the relevant CLI flow. This can also be done with a normal CLI run. ```bash make dev-run ``` -------------------------------- ### Use PEP 249 Cursor Object for Queries Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Interact with Databend using a standard PEP 249 cursor object for executing SQL statements and fetching results. This provides a familiar interface for database interactions. ```python from databend_driver import BlockingDatabendClient client = BlockingDatabendClient('databend://root:root@localhost:8000/?sslmode=disable') cursor = client.cursor() cursor.execute( """ CREATE TABLE test ( i64 Int64, u64 UInt64, f64 Float64, s String, s2 String, d Date, t DateTime ) """ ) cursor.execute("INSERT INTO test VALUES (?, ?, ?, ?, ?, ?, ?)", (1, 1, 1.0, 'hello', 'world', '2021-01-01', '2021-01-01 00:00:00')) cursor.execute("SELECT * FROM test") rows = cursor.fetchall() for row in rows: print(row.values()) cursor.close() ``` -------------------------------- ### Show Server Query ID Source: https://github.com/databendlabs/bendsql/blob/main/cli/README.md Execute a query and display the server-generated query ID, useful for tracking queries. ```sh ❯ bendsql --query-id --query "select 1" Query ID: 01c0c277-0004-011f-0000-000a83ee9129 1 ``` -------------------------------- ### Connect to Local Embedded Databend with connect_local Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Use the connect_local function for more direct control over local embedded Databend connections, specifying parameters like database or data path. ```python from databend_driver import connect_local conn = connect_local(database=":memory:") conn = connect_local(data_path="./local-state", tenant="default") ``` -------------------------------- ### connect_local Function Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Function to establish a local connection to Databend, supporting in-memory databases and specified data paths. ```APIDOC ## connect_local ### Signature def connect_local( database: str = ":memory:", *, data_path: str | None = None, tenant: str | None = None, ) -> LocalConnection: ... ### Description Establishes a local connection to Databend. It can create an in-memory database or use a specified data path. Optional tenant can also be provided. ### Parameters - **database** (str, optional) - The name of the database to connect to. Defaults to ":memory:". - **data_path** (str | None, optional) - The path to the data directory for the database. - **tenant** (str | None, optional) - The tenant to use for the connection. ``` -------------------------------- ### Connect to Local Embedded Databend Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Connect to a local embedded Databend instance for testing or offline workflows. The state can be persistent or in-memory. ```python from databend_driver import connect # Persistent state stored under ./local-state conn = connect("databend+local:///./local-state") conn.exec("CREATE TABLE books(id INT, title STRING)") conn.exec("INSERT INTO books VALUES (1, 'Databend')") row = conn.query_row("SELECT title FROM books ORDER BY id LIMIT 1") print(row.values()) # ('Databend',) rows = [row.values() for row in conn.query_iter("SELECT * FROM books ORDER BY id")] ``` -------------------------------- ### Query Single Row with Builder Pattern Source: https://github.com/databendlabs/bendsql/blob/main/driver/README.md Fetches a single row from the 'books' table using the query builder and parameter binding. ```rust // Using Builder pattern for better flexibility let row = conn.query("SELECT * FROM books WHERE title = ?") .bind(params!["The Little Prince"]) .one() .await.unwrap() ``` -------------------------------- ### AsyncDatabendConnection Methods Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Provides methods for asynchronous interaction with a Databend connection, including retrieving connection info, executing queries, and loading data. ```APIDOC ## AsyncDatabendConnection ### Methods - **info()** -> ConnectionInfo Description: Retrieves information about the current Databend connection. - **version()** -> str Description: Gets the Databend server version. - **close()** -> None Description: Closes the asynchronous connection. - **last_query_id()** -> str | None Description: Returns the ID of the last executed query. - **kill_query(query_id: str)** -> None Description: Asynchronously cancels a running query. Parameters: - **query_id** (str) - The ID of the query to kill. - **exec(sql: str, params: list[string] | tuple[string] | any = None)** -> int Description: Asynchronously executes a SQL statement and returns the number of rows affected. Parameters: - **sql** (str) - The SQL statement to execute. - **params** (list[string] | tuple[string] | any, optional) - Parameters for the SQL statement. - **query_row(sql: str, params: list[string] | tuple[string] | any = None)** -> Row Description: Asynchronously executes a SQL query and returns a single row. Parameters: - **sql** (str) - The SQL query to execute. - **params** (list[string] | tuple[string] | any, optional) - Parameters for the SQL query. - **query_iter(sql: str, params: list[string] | tuple[string] | any = None)** -> RowIterator Description: Asynchronously executes a SQL query and returns an iterator over the rows. Parameters: - **sql** (str) - The SQL query to execute. - **params** (list[string] | tuple[string] | any, optional) - Parameters for the SQL query. - **stream_load(sql: str, data: list[list[str]], method: str = None)** -> ServerStats Description: Asynchronously streams data into a table. Parameters: - **sql** (str) - The SQL statement for loading data. - **data** (list[list[str]]) - The data to stream. - **method** (str, optional) - The loading method. - **load_file(sql: str, file: str, method: str = None)** -> ServerStats Description: Asynchronously loads data from a file into a table. Parameters: - **sql** (str) - The SQL statement for loading data. - **file** (str) - The path to the file to load. - **method** (str, optional) - The loading method. ``` -------------------------------- ### Register External Data as Virtual Tables Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Register local files (Parquet, CSV, JSON, text) or in-memory DataFrames as virtual tables for querying. This allows seamless integration of external data sources. ```python # Register a Parquet file conn.register("sales", "./data/sales.parquet") conn.sql("SELECT * FROM sales LIMIT 10").df() # Register a CSV file conn.register("events", "./data/events.csv") # Register a pandas or polars DataFrame import pandas as pd df = pd.DataFrame({"id": [1, 2], "name": ["Alice", "Bob"]}) conn.register("users", df) # Shorthand: register a DataFrame and return a relation immediately relation = conn.from_df(df) # Read helpers (register and return relation in one call) relation = conn.read_parquet("./data/sales.parquet") relation = conn.read_csv("./data/events.csv") relation = conn.read_json("./data/logs.ndjson") relation = conn.read_text("./data/raw.txt") ``` -------------------------------- ### PEP 249 Exception Classes Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Lists the standard PEP 249 compliant exception classes provided by the Databend driver for error handling. ```python # Base exceptions class Warning(Exception): ... class Error(Exception): ... # Interface errors class InterfaceError(Error): ... # Database errors class DatabaseError(Error): ... # Specific database error types class DataError(DatabaseError): ... class OperationalError(DatabaseError): ... class IntegrityError(DatabaseError): ... class InternalError(DatabaseError): ... class ProgrammingError(DatabaseError): ... class NotSupportedError(DatabaseError): ... ``` -------------------------------- ### LocalConnection Class Definition Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Defines the LocalConnection class, which handles local data interactions. It includes methods for executing SQL, registering data sources, and reading various file formats. ```python class LocalConnection: def sql(self, query: str) -> LocalRelation: ... def table(self, name: str) -> LocalRelation: ... def format_sql(self, sql: str, params: Any = None) -> str: ... def execute(self, query: str, params: Any = None) -> None: ... def exec(self, sql: str, params: Any = None) -> None: ... def query_row(self, sql: str, params: Any = None) -> LocalRow | None: ... def query_all(self, sql: str, params: Any = None) -> list[LocalRow]: ... def query_iter(self, sql: str, params: Any = None) -> LocalRowIterator: ... def close(self) -> None: ... def last_query_id(self) -> None: ... # always None for local mode def kill_query(self, query_id: str) -> None: ... # raises NotImplementedError def register( self, name: str, source: Any, # path str/Path, pandas/polars DataFrame, or pyarrow Table *, format: str | None = None, pattern: str | None = None, connection: str | None = None, ) -> LocalConnection: ... def from_df(self, source: Any, *, name: str | None = None) -> LocalRelation: ... def read_parquet( self, path: str | Path, *, pattern: str | None = None, connection: str | None = None, name: str | None = None, ) -> LocalRelation: ... def read_csv( self, path: str | Path, *, pattern: str | None = None, connection: str | None = None, name: str | None = None, ) -> LocalRelation: ... def read_json( self, path: str | Path, *, pattern: str | None = None, connection: str | None = None, name: str | None = None, ) -> LocalRelation: ... def read_text( self, path: str | Path, *, pattern: str | None = None, connection: str | None = None, name: str | None = None, ) -> LocalRelation: ... ``` -------------------------------- ### BlockingDatabendClient Methods Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Provides methods for creating blocking connections and cursors to Databend. ```APIDOC ## BlockingDatabendClient ### Initialization - **__init__(dsn: str)** Description: Initializes the blocking Databend client with a Data Source Name (DSN). Parameters: - **dsn** (str) - The Data Source Name for the connection. ### Methods - **get_conn()** -> BlockingDatabendConnection Description: Returns a new blocking Databend connection. - **cursor()** -> BlockingDatabendCursor Description: Returns a new blocking Databend cursor. ``` -------------------------------- ### Execute Query via StdIn Pipe Source: https://github.com/databendlabs/bendsql/blob/main/cli/README.md Pipe a SQL query string to BendSQL for execution using the flight SQL protocol. ```sh ❯ echo "select number from numbers(3)" | bendsql -h localhost --port 8900 --flight 0 1 2 ``` -------------------------------- ### Convert VARIANT to Object with Helper Function Source: https://github.com/databendlabs/bendsql/blob/main/bindings/nodejs/README.md Demonstrates using a helper function in the Databend Node.js client to automatically convert VARIANT data types to JavaScript objects. ```javascript const row = await conn.queryRow("SELECT * FROM example limit 1;"); row.setOpts({ variantAsObject: true }); console.log(row.data()); ``` -------------------------------- ### Handling GEOMETRY/GEOGRAPHY Binary Output Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Verifies that Databend's GEOMETRY/GEOGRAPHY types return `bytes` when `geometry_output_format` is set to a binary format like 'WKB'. ```python row = await conn.query_row("settings(geometry_output_format='WKB') SELECT st_point(60, 37)") assert isinstance(row.values()[0], bytes) ``` -------------------------------- ### Generate TPCH Dataset Source: https://github.com/databendlabs/bendsql/blob/main/cli/README.md Use the `gendata` command to generate a TPCH dataset with a scale factor of 0.01. The `override` option is set to 1 to ensure the data is generated. ```sql root@localhost:8000/test> gendata(tpch, sf = 0.01, override = 1); ┌─────────────────────────────┐ │ table │ status │ size │ │ String │ String │ UInt64 │ ├──────────┼────────┼─────────┤ │ customer │ OK │ 130089 │ │ lineitem │ OK │ 2551994 │ │ nation │ OK │ 2195 │ │ orders │ OK │ 598190 │ │ part │ OK │ 77400 │ │ partsupp │ OK │ 437252 │ │ region │ OK │ 1018 │ │ supplier │ OK │ 10653 │ └─────────────────────────────┘ ``` -------------------------------- ### ServerStats Object Properties Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Contains statistics about server operations, such as total rows, bytes, and running time. ```python class ServerStats: @property def total_rows(self) -> int: ... @property def total_bytes(self) -> int: ... @property def read_rows(self) -> int: ... @property def read_bytes(self) -> int: ... @property def write_rows(self) -> int: ... @property def write_bytes(self) -> int: ... @property def running_time_ms(self) -> float: ... ``` -------------------------------- ### Query Multiple Rows Source: https://github.com/databendlabs/bendsql/blob/main/driver/README.md Retrieves all rows or processes rows as a stream from the 'books' table. ```rust // Get all rows let rows = conn.query("SELECT * FROM books").all().await.unwrap(); for row in rows { let (title, author, date): (String, String, chrono::NaiveDate) = row.try_into().unwrap(); println!("{} {} {}", title, author, date); } // Stream processing for large datasets let mut iter = conn.query("SELECT * FROM books").iter().await.unwrap(); while let Some(row) = iter.next().await { let (title, author, date): (String, String, chrono::NaiveDate) = row.unwrap().try_into().unwrap(); println!("{} {} {}", title, author, date); } ``` -------------------------------- ### BlockingDatabendConnection Methods Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Provides methods for blocking interaction with a Databend connection, including retrieving connection info, executing queries, and loading data. ```APIDOC ## BlockingDatabendConnection ### Methods - **info()** -> ConnectionInfo Description: Retrieves information about the current Databend connection. - **version()** -> str Description: Gets the Databend server version. - **close()** -> None Description: Closes the blocking connection. - **last_query_id()** -> str | None Description: Returns the ID of the last executed query. - **kill_query(query_id: str)** -> None Description: Cancels a running query. Parameters: - **query_id** (str) - The ID of the query to kill. - **exec(sql: str, params: list[string] | tuple[string] | any = None)** -> int Description: Executes a SQL statement and returns the number of rows affected. Parameters: - **sql** (str) - The SQL statement to execute. - **params** (list[string] | tuple[string] | any, optional) - Parameters for the SQL statement. - **query_row(sql: str, params: list[string] | tuple[string] | any = None)** -> Row Description: Executes a SQL query and returns a single row. Parameters: - **sql** (str) - The SQL query to execute. - **params** (list[string] | tuple[string] | any, optional) - Parameters for the SQL query. - **query_iter(sql: str, params: list[string] | tuple[string] | any = None)** -> RowIterator Description: Executes a SQL query and returns an iterator over the rows. Parameters: - **sql** (str) - The SQL query to execute. - **params** (list[string] | tuple[string] | any, optional) - Parameters for the SQL query. - **stream_load(sql: str, data: list[list[str]], method: str = None)** -> ServerStats Description: Streams data into a table. Parameters: - **sql** (str) - The SQL statement for loading data. - **data** (list[list[str]]) - The data to stream. - **method** (str, optional) - The loading method. - **load_file(sql: str, file: str, method: str = None, format_option: dict = None, copy_options: dict = None)** -> ServerStats Description: Loads data from a file into a table. Parameters: - **sql** (str) - The SQL statement for loading data. - **file** (str) - The path to the file to load. - **method** (str, optional) - The loading method. - **format_option** (dict, optional) - Options for data format. - **copy_options** (dict, optional) - Options for the COPY command. ``` -------------------------------- ### Handling VARIANT Data Type Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Demonstrates how to parse JSON-encoded VARIANT data from Databend into Python dictionaries using the `json` module. ```sql CREATE TABLE example ( data VARIANT ); INSERT INTO example VALUES ('{"a": 1, "b": "hello"}'); ``` ```python import json row = await conn.query_row("SELECT * FROM example limit 1;") data = row.values()[0] value = json.loads(data) print(value) ``` -------------------------------- ### Parse VARIANT Data Type in Node.js Source: https://github.com/databendlabs/bendsql/blob/main/bindings/nodejs/README.md Shows how to retrieve and parse data from a VARIANT column in Databend using the Node.js client. Demonstrates JSON parsing for structured data. ```javascript const row = await conn.queryRow("SELECT * FROM example limit 1;"); const data = row.values()[0]; const value = JSON.parse(data); console.log(value); ``` -------------------------------- ### Use Blocking Connection Object for Queries Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Utilize the BlockingDatabendClient to obtain a blocking connection object for executing SQL queries and iterating over results. This is suitable for synchronous applications. ```python from databend_driver import BlockingDatabendClient client = BlockingDatabendClient('databend://root:root@localhost:8000/?sslmode=disable') conn = client.get_conn() conn.exec( """ CREATE TABLE test ( i64 Int64, u64 UInt64, f64 Float64, s String, s2 String, d Date, t DateTime ) """ ) rows = conn.query_iter("SELECT * FROM test") for row in rows: print(row.values()) conn.close() ``` -------------------------------- ### Schema Object Methods Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Represents the schema of a query result. Provides access to the list of fields in the schema. ```python class Schema: def fields(self) -> list[Field]: ... ``` -------------------------------- ### Row Object Methods Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Represents a single row of data returned from a query. Provides methods to access row values and iterate over them. ```python class Row: def values(self) -> tuple: ... def __len__(self) -> int: ... def __iter__(self) -> Row: ... def __next__(self) -> any: ... def __dict__(self) -> dict: ... def __getitem__(self, key: int | str) -> any: ... ``` -------------------------------- ### BlockingDatabendCursor Methods Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Provides methods for interacting with a Databend database using a blocking cursor, supporting query execution and data fetching. ```APIDOC ## BlockingDatabendCursor ### Properties - **description** -> list[tuple[str, str, int | None, int | None, int | None, int | None, bool | None]] | None Description: Returns a description of the cursor's results. - **rowcount** -> int Description: Returns the number of rows affected by the last operation. ### Methods - **close()** -> None Description: Closes the cursor. - **execute(operation: str, params: list[string] | tuple[string] = None)** -> None | int Description: Executes a single SQL command. Parameters: - **operation** (str) - The SQL command to execute. - **params** (list[string] | tuple[string], optional) - Parameters for the SQL command. - **executemany(operation: str, params: list[string] | tuple[string] = None, values: list[list[string] | tuple[string]])** -> None | int Description: Executes a SQL command multiple times with different parameter sets. Parameters: - **operation** (str) - The SQL command to execute. - **params** (list[string] | tuple[string], optional) - Default parameters for the SQL command. - **values** (list[list[string] | tuple[string]]) - A sequence of parameter sets to execute. - **fetchone()** -> Row | None Description: Fetches the next row of a query result set, returning a single row or None. - **fetchmany(size: int = 1)** -> list[Row] Description: Fetches the next set of rows of a query result, returning a list of rows. Parameters: - **size** (int, optional) - The number of rows to fetch. Defaults to 1. - **fetchall()** -> list[Row] Description: Fetches all remaining rows of a query result, returning them as a list of rows. ### Optional DB API Extensions - **next()** -> Row Description: Retrieves the next row from the result set. - **__next__()** -> Row Description: Retrieves the next row from the result set (iterator protocol). - **__iter__()** -> BlockingDatabendCursor Description: Returns the cursor itself as an iterator. ``` -------------------------------- ### AsyncDatabendConnection Interface Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Defines the asynchronous methods for interacting with a Databend database connection. Use for non-blocking database operations. ```python class AsyncDatabendConnection: async def info(self) -> ConnectionInfo: ... async def version(self) -> str: ... async def close(self) -> None: ... def last_query_id(self) -> str | None: ... async def kill_query(self, query_id: str) -> None: ... async def exec(self, sql: str, params: list[string] | tuple[string] | any = None) -> int: ... async def query_row(self, sql: str, params: list[string] | tuple[string] | any = None) -> Row: ... async def query_iter(self, sql: str, params: list[string] | tuple[string] | any = None) -> RowIterator: ... async def stream_load(self, sql: str, data: list[list[str]], method: str = None) -> ServerStats: ... async def load_file(self, sql: str, file: str, method: str = None) -> ServerStats: ... ``` -------------------------------- ### BlockingDatabendConnection Interface Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Defines the synchronous methods for interacting with a Databend database connection. Suitable for blocking database operations. ```python class BlockingDatabendConnection: def info(self) -> ConnectionInfo: ... def version(self) -> str: ... def close(self) -> None: ... def last_query_id(self) -> str | None: ... def kill_query(self, query_id: str) -> None: ... def exec(self, sql: str, params: list[string] | tuple[string] | any = None) -> int: ... def query_row(self, sql: str, params: list[string] | tuple[string] | any = None) -> Row: ... def query_iter(self, sql: str, params: list[string] | tuple[string] | any = None) -> RowIterator: ... def stream_load(self, sql: str, data: list[list[str]], method: str = None) -> ServerStats: ... def load_file(self, sql: str, file: str, method: str = None, format_option: dict = None, copy_options: dict = None) -> ServerStats: ... ``` -------------------------------- ### BlockingDatabendCursor Interface Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Provides a cursor for executing SQL statements and fetching results in a blocking manner. Supports standard DB API extensions. ```python class BlockingDatabendCursor: @property def description(self) -> list[tuple[str, str, int | None, int | None, int | None, int | None, bool | None]] | None: ... @property def rowcount(self) -> int: ... def close(self) -> None: ... def execute(self, operation: str, params: list[string] | tuple[string] = None) -> None | int: ... def executemany(self, operation: str, params: list[string] | tuple[string] = None, values: list[list[string] | tuple[string]]) -> None | int: ... def fetchone(self) -> Row | None: ... def fetchmany(self, size: int = 1) -> list[Row]: ... def fetchall(self) -> list[Row]: ... # Optional DB API Extensions def next(self) -> Row: ... def __next__(self) -> Row: ... def __iter__(self) -> BlockingDatabendCursor: ... ``` -------------------------------- ### Field Object Properties Source: https://github.com/databendlabs/bendsql/blob/main/bindings/python/README.md Represents a field within a schema. Provides access to the field's name and data type. ```python class Field: @property def name(self) -> str: ... @property def data_type(self) -> str: ... ```