Skip to content

Commit

Permalink
Merge pull request #3013 from szarnyasg/nits-20240608b
Browse files Browse the repository at this point in the history
Format Python examples
  • Loading branch information
szarnyasg authored Jun 8, 2024
2 parents dbc171c + 3d8d0aa commit 0a3e71e
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 23 deletions.
33 changes: 25 additions & 8 deletions docs/api/python/dbapi.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,24 +92,38 @@ The `description` property of the connection object contains the column names as

DuckDB also supports [prepared statements](../../sql/query_syntax/prepared_statements) in the API with the `execute` and `executemany` methods. The values may be passed as an additional parameter after a query that contains `?` or `$1` (dollar symbol and a number) placeholders. Using the `?` notation adds the values in the same sequence as passed within the Python parameter. Using the `$` notation allows for values to be reused within the SQL statement based on the number and index of the value found within the Python parameter. Values are converted according to the [conversion rules](conversion#object-conversion-python-object-to-duckdb).

Here are some examples:
Here are some examples. First, insert a row using a [prepared statement](../../sql/query_syntax/prepared_statements):

```python
# insert a row using prepared statements
con.execute("INSERT INTO items VALUES (?, ?, ?)", ["laptop", 2000, 1])
```

Second, insert several rows using a [prepared statement](../../sql/query_syntax/prepared_statements):

# insert several rows using prepared statements
```python
con.executemany("INSERT INTO items VALUES (?, ?, ?)", [["chainsaw", 500, 10], ["iphone", 300, 2]] )
```

Query the database using a [prepared statement](../../sql/query_syntax/prepared_statements):

# query the database using a prepared statement
```python
con.execute("SELECT item FROM items WHERE value > ?", [400])
print(con.fetchall())
# [('laptop',), ('chainsaw',)]
```

```text
[('laptop',), ('chainsaw',)]
```

Query using the `$` notation for a [prepared statement](../../sql/query_syntax/prepared_statements) and reused values:

# query using $ notation for prepared statement and reused values
```python
con.execute("SELECT $1, $1, $2", ["duck", "goose"])
print(con.fetchall())
# [('duck', 'duck', 'goose')]
```

```text
[('duck', 'duck', 'goose')]
```

> Warning Do *not* use `executemany` to insert large amounts of data into DuckDB. See the [data ingestion page](data_ingestion) for better options.
Expand All @@ -136,5 +150,8 @@ res = duckdb.execute("""
}
).fetchall()
print(res)
# [(5, 'DuckDB', [42])]
```

```text
[(5, 'DuckDB', [42])]
```
56 changes: 47 additions & 9 deletions docs/api/python/function.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ def generate_random_name():
duckdb.create_function("random_name", generate_random_name, [], VARCHAR)
res = duckdb.sql("SELECT random_name()").fetchall()
print(res)
# [('Gerald Ashley',)]
```

```text
[('Gerald Ashley',)]
```

## Creating Functions
Expand Down Expand Up @@ -63,7 +66,7 @@ def my_function(x: int) -> str:
return x

duckdb.create_function("my_func", my_function)
duckdb.sql("SELECT my_func(42)")
print(duckdb.sql("SELECT my_func(42)"))
```

```text
Expand Down Expand Up @@ -92,13 +95,28 @@ def dont_intercept_null(x):
duckdb.create_function("dont_intercept", dont_intercept_null, [BIGINT], BIGINT)
res = duckdb.sql("SELECT dont_intercept(NULL)").fetchall()
print(res)
# [(None,)]
```

```text
[(None,)]
```

With `null_handling="special"`:

```python
import duckdb
from duckdb.typing import *

def dont_intercept_null(x):
return 5

duckdb.remove_function("dont_intercept")
duckdb.create_function("dont_intercept", dont_intercept_null, [BIGINT], BIGINT, null_handling="special")
res = duckdb.sql("SELECT dont_intercept(NULL)").fetchall()
print(res)
# [(5,)]
```

```text
[(5,)]
```

## Exception Handling
Expand All @@ -122,7 +140,18 @@ except duckdb.InvalidInputException as e:
duckdb.create_function("doesnt_throw", will_throw, [], BIGINT, exception_handling="return_null")
res = duckdb.sql("SELECT doesnt_throw()").fetchall()
print(res)
# [(None,)]
```

```console
Invalid Input Error: Python exception occurred while executing the UDF: ValueError: ERROR

At:
...(5): will_throw
...(9): <module>
```

```text
[(None,)]
```

## Side Effects
Expand All @@ -148,7 +177,10 @@ con = duckdb.connect()
con.create_function("my_counter", count, side_effects = False)
res = con.sql("SELECT my_counter() FROM range(10)").fetchall()
print(res)
# [(0,), (0,), (0,), (0,), (0,), (0,), (0,), (0,), (0,), (0,)]
```

```text
[(0,), (0,), (0,), (0,), (0,), (0,), (0,), (0,), (0,), (0,)]
```

Which is obviously not the desired result, when we add `side_effects = True`, the result is as we would expect:
Expand All @@ -159,7 +191,10 @@ count.counter = 0
con.create_function("my_counter", count, side_effects = True)
res = con.sql("SELECT my_counter() FROM range(10)").fetchall()
print(res)
# [(0,), (1,), (2,), (3,), (4,), (5,), (6,), (7,), (8,), (9,)]
```

```text
[(0,), (1,), (2,), (3,), (4,), (5,), (6,), (7,), (8,), (9,)]
```

## Python Function Types
Expand Down Expand Up @@ -190,5 +225,8 @@ def random_date():
duckdb.create_function("random_date", random_date, [], DATE, type="native")
res = duckdb.sql("SELECT random_date()").fetchall()
print(res)
# [(datetime.date(2019, 5, 15),)]
```

```text
[(datetime.date(2019, 5, 15),)]
```
21 changes: 15 additions & 6 deletions docs/api/python/types.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,11 @@ duckdb.typing.DuckDBPyType(list[dict[Union[str, int], str])
```python
import duckdb

duckdb.typing.DuckDBPyType(dict[str, int])
# MAP(VARCHAR, BIGINT)
print(duckdb.typing.DuckDBPyType(dict[str, int]))
```

```text
MAP(VARCHAR, BIGINT)
```

#### *`{'a': field_one, 'b': field_two, .., 'n': field_n}`*
Expand All @@ -78,8 +81,11 @@ duckdb.typing.DuckDBPyType(dict[str, int])
```python
import duckdb

duckdb.typing.DuckDBPyType({'a': str, 'b': int})
# STRUCT(a VARCHAR, b BIGINT)
print(duckdb.typing.DuckDBPyType({'a': str, 'b': int}))
```

```text
STRUCT(a VARCHAR, b BIGINT)
```

#### *`Union[⟨type_1⟩, ... ⟨type_n⟩]`*
Expand All @@ -90,8 +96,11 @@ duckdb.typing.DuckDBPyType({'a': str, 'b': int})
import duckdb
from typing import Union

duckdb.typing.DuckDBPyType(Union[int, str, bool, bytearray])
# UNION(u1 BIGINT, u2 VARCHAR, u3 BOOLEAN, u4 BLOB)
print(duckdb.typing.DuckDBPyType(Union[int, str, bool, bytearray]))
```

```text
UNION(u1 BIGINT, u2 VARCHAR, u3 BOOLEAN, u4 BLOB)
```

### Creation Functions
Expand Down

0 comments on commit 0a3e71e

Please sign in to comment.