# fastduck


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

`fastduck` provides some development experience improvements for the
standard `duckdb` python API.

## Install

``` sh
pip install fastduck
```

## How to use

~~import fastduck as fuck~~

``` python
from fastduck import database
```

``` python
db = database('../data/chinook.duckdb')
db
```

    IOException: IO Error: Could not set lock on file "/Users/fredguth/Code/jeremy/fastduck/nbs/../data/chinook.duckdb": Conflicting lock is held in /opt/anaconda3/envs/fastduck/bin/python3.12 (PID 51108) by user fredguth. See also https://duckdb.org/docs/connect/concurrency

``` python
dt = db.t
dt
```

You can use this to grab a single table…

``` python
artist = dt.Artist
artist
```

``` python
customer = dt['Customer']
customer
```

… or multiple tables at once:

``` python
dt['Artist', 'Album', 'Genre']
```

It also provides auto-complete in Jupyter, IPython and nearly any other
interactive Python environment:

<img src="nbs/images/autocomplete.png" width="400"
alt="Autocomplete in Jupyter" />

You can check if a table is in the database already:

``` python
'Artist' in dt
```

Column work in a similar way to tables, using the `c` property:

``` python
ac = artist.c
ac, artist.columns
```

Auto-complete works for columns too:

<img src="nbs/images/columns_complete.png" width="300"
alt="Columns autocomplete in Jupyter" />

The tables and views of a database got some interesting new attributes….

``` python
artist.meta
```

``` python
artist.model
```

``` python
artist.cls, type(artist.cls)
```

`duckdb` replacement scans keep working and are wonderful for usage in
SQL statements:

``` python
db.sql("select * from artist where artist.Name like 'AC/%'")
```

You can view the results of a query as records

``` python
db.sql("select * from artist where artist.Name like 'AC/%'").to_recs()
```

or as a list of lists

``` python
db.sql("select * from artist where artist.Name like 'AC/%'").to_list()
```

And you there is also an alias for `sql` with `to_recs` simply called
`q`

``` python
db.q("select * from artist where artist.Name like 'AC/%'")
```

#### Dataclass support

As we briefly saw, a `dataclass` type with the names, types and defaults
of the table is added to the Relation:

``` python
abm = db.t.Album
art = db.t.Artist
acca_sql = f"""
select abm.* 
from abm join art using (ArtistID)
where art.Name like 'AC/%'
"""
acca_dacca = db.q(acca_sql)
acca_dacca
```

``` python
let_b_rock_obj = abm.cls(**acca_dacca[-1])
let_b_rock_obj
```

You can get the definition of the dataclass using fastcore’s
`dataclass_src` – everything is treated as nullable, in order to handle
auto-generated database values:

``` python
from fastcore.xtras import hl_md, dataclass_src

src = dataclass_src(db.t.Album.cls)
hl_md(src, 'python')
```
