This page leverages some basic transform syntax from later parts of the
walkthrough. Don’t worry too much about it for now: the core purpose of
this page is to understand how relations work in Vinyl.
Properties
As in SQL, relations are the core data model. But relations in Vinyl have some unique properties:Relations are column aware
Take theseattle_weather
dataset from vinyl’s examples.
weather
is a Vinytable object and carries far more information that a
standard sql table or cte. The schema, for example, can be pulled easily
without running a query against the database.
┏━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┓
┃ # ┃ column ┃ type ┃
┡━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━┩
│ 0 │ date │ timestamp(6) │
│ 1 │ precipitation │ float64 │
│ 2 │ temp_max │ float64 │
│ 3 │ temp_min │ float64 │
│ 4 │ wind │ float64 │
│ 5 │ weather │ string │
└───┴───────────────┴──────────────┘
wind
column.
┏━━━┳━━━━━━━━━━┳━━━━━━━━━┓
┃ # ┃ column ┃ type ┃
┡━━━╇━━━━━━━━━━╇━━━━━━━━━┩
│ 0 │ temp_max │ float64 │
│ 1 │ temp_min │ float64 │
└───┴──────────┴─────────┘
weather
.
Relations are lazy
Vinyl keeps track of its syntax lazily, and only compiles when a variable is executed or its sql is generated. By default, vinyl will return a string representation of the ast associated with a table unless specified otherwise. For example:.visualize()
:
╭──────────────────────╮
│ Project │
╭──────────────────────▶│ temp_max: float64 │
│ │ temp_min: float64 │
│ ╰──────────────────────╯
│ ▲▲
│ ││
│ ││
│ ││
╭─────────────────╮ ╭─────────────────╮
│ temp_max: Field │ │ temp_min: Field │
│ :: float64 │ │ :: float64 │
╰─────────────────╯ ╰─────────────────╯
▲ ▲│
│ ││
│ ││
│ ││
│ ││
│ ╭────────────────────────────────╮
│ │ seattle_weather: DatabaseTable │
│ │ date: timestamp(6) │
│ │ precipitation: float64 │
╰──────────────────│ temp_max: float64 │
│ temp_min: float64 │
│ wind: float64 │
│ weather: string │
╰────────────────────────────────╯
temp_max | temp_min | |
---|---|---|
0 | 12.8 | 5.0 |
1 | 10.6 | 2.8 |
2 | 11.7 | 7.2 |
3 | 12.2 | 5.6 |
4 | 8.9 | 2.8 |
… | … | … |
1456 | 4.4 | 1.7 |
1457 | 5.0 | 1.7 |
1458 | 7.2 | 0.6 |
1459 | 5.6 | -1.0 |
1460 | 5.6 | -2.1 |
1461 rows × 2 columns
┏━━━━━━━━━━┳━━━━━━━━━━┓
┃ temp_max ┃ temp_min ┃
┡━━━━━━━━━━╇━━━━━━━━━━┩
│ float64 │ float64 │
├──────────┼──────────┤
│ 12.8 │ 5.0 │
│ 10.6 │ 2.8 │
│ 11.7 │ 7.2 │
│ 12.2 │ 5.6 │
│ 8.9 │ 2.8 │
│ 4.4 │ 2.2 │
│ 7.2 │ 2.8 │
│ 10.0 │ 2.8 │
│ 9.4 │ 5.0 │
│ 6.1 │ 0.6 │
│ … │ … │
└──────────┴──────────┘
.save()
.
Relations are selectively mutable
By default, VinylTables are immutable. For example, the original table ast is printed when run is the same as the originalweather
.
@model
or @metric
decorator) 2. Context managers
The first case is designed to support
:
This can be done more efficiently in vinyl using a window function, but
this is a good example of how to use the context manager.
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ date ┃ Subtract(wind, avg_wind) ┃
┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ timestamp(6) │ float64 │
├─────────────────────┼──────────────────────────┤
│ 2012-01-01 00:00:00 │ 0.8 │
│ 2012-01-02 00:00:00 │ 0.6 │
│ 2012-01-03 00:00:00 │ -1.6 │
│ 2012-01-04 00:00:00 │ 0.8 │
│ 2012-01-05 00:00:00 │ 2.2 │
│ 2012-01-06 00:00:00 │ -1.7 │
│ 2012-01-07 00:00:00 │ -1.6 │
│ 2012-01-08 00:00:00 │ -1.9 │
│ 2012-01-09 00:00:00 │ -0.5 │
│ 2012-01-10 00:00:00 │ -0.5 │
│ … │ … │
└─────────────────────┴──────────────────────────┘
Relations are dialect-independent
Vinyl uses the Ibis library to generate SQL. This means that you can write your queries in a dialect agnostic way. For example, the following code works in across the dialects currently supported by Vinyl:- BigQuery
- Snowflake
- DuckDB
- Postgres
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓
┃ month ┃ temp_max ┃
┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩
│ timestamp │ array<float64> │
├─────────────────────┼────────────────┤
│ │ [ │
│ │ 12.8, │
│ │ 10.6, │
│ │ 11.7, │
│ │ 12.2, │
│ │ 8.9, │
│ │ 4.4, │
│ │ 7.2, │
│ │ 10.0, │
│ │ 9.4, │
│ │ 6.1, │
│ │ 6.1, │
│ │ 6.1, │
│ │ 5.0, │
│ │ 4.4, │
│ │ 1.1, │
│ 2012-01-01 00:00:00 │ 1.7, │
│ │ 3.3, │
│ │ 0.0, │
│ │ -1.1, │
│ │ 7.2, │
│ │ 8.3, │
│ │ 6.7, │
│ │ 8.3, │
│ │ 10.0, │
│ │ 8.9, │
│ │ 8.9, │
│ │ 6.7, │
│ │ 6.7, │
│ │ 9.4, │
│ │ 8.3, │
│ │ 9.4 │
│ │ ] │
│ │ [ │
│ │ 8.9, │
│ │ 8.3, │
│ │ 14.4, │
│ │ 15.6, │
│ │ 13.9, │
│ │ 16.1, │
│ │ 15.6, │
│ │ 10.0, │
│ │ 11.1, │
│ │ 12.8, │
│ │ 8.9, │
│ │ 8.3, │
│ │ 7.2, │
│ │ 6.7, │
│ 2012-02-01 00:00:00 │ 7.2, │
│ │ 7.2, │
│ │ 10.0, │
│ │ 6.7, │
│ │ 6.7, │
│ │ 7.8, │
│ │ 10.0, │
│ │ 10.0, │
│ │ 8.3, │
│ │ 6.7, │
│ │ 7.2, │
│ │ 5.0, │
│ │ 6.7, │
│ │ 6.7, │
│ │ 5.0 │
│ │ ] │
│ │ [ │
│ │ 6.1, │
│ │ 6.7, │
│ │ 12.2, │
│ │ 10.6, │
│ │ 7.8, │
│ │ 6.7, │
│ │ 8.9, │
│ │ 15.6, │
│ │ 9.4, │
│ │ 7.2, │
│ │ 6.7, │
│ │ 8.3, │
│ │ 5.6, │
│ │ 7.8, │
│ │ 11.1, │
│ 2012-03-01 00:00:00 │ 8.9, │
│ │ 10.0, │
│ │ 5.0, │
│ │ 7.2, │
│ │ 7.8, │
│ │ 8.9, │
│ │ 10.0, │
│ │ 12.2, │
│ │ 15.0, │
│ │ 13.3, │
│ │ 12.8, │
│ │ 14.4, │
│ │ 10.6, │
│ │ 10.0, │
│ │ 9.4, │
│ │ 10.0 │
│ │ ] │
│ │ [ │
│ │ 8.9, │
│ │ 16.7, │
│ │ 11.7, │
│ │ 10.6, │
│ │ 9.4, │
│ │ 11.1, │
│ │ 16.1, │
│ │ 21.1, │
│ │ 20.0, │
│ │ 17.8, │
│ │ 11.1, │
│ │ 13.9, │
│ │ 15.0, │
│ │ 15.6, │
│ 2012-04-01 00:00:00 │ 16.1, │
│ │ 13.3, │
│ │ 10.0, │
│ │ 13.3, │
│ │ 13.9, │
│ │ 13.3, │
│ │ 20.0, │
│ │ 23.3, │
│ │ 21.7, │
│ │ 13.9, │
│ │ 16.7, │
│ │ 13.9, │
│ │ 13.3, │
│ │ 16.1, │
│ │ 15.6, │
│ │ 12.8 │
│ │ ] │
│ │ [ │
│ │ 11.7, │
│ │ 13.3, │
│ │ 11.1, │
│ │ 12.2, │
│ │ 13.3, │
│ │ 17.8, │
│ │ 23.9, │
│ │ 18.3, │
│ │ 13.3, │
│ │ 14.4, │
│ │ 18.3, │
│ │ 24.4, │
│ │ 25.6, │
│ │ 26.7, │
│ │ 24.4, │
│ 2012-05-01 00:00:00 │ 19.4, │
│ │ 17.8, │
│ │ 15.6, │
│ │ 19.4, │
│ │ 14.4, │
│ │ 16.7, │
│ │ 12.8, │
│ │ 14.4, │
│ │ 17.2, │
│ │ 22.2, │
│ │ 22.2, │
│ │ 17.2, │
│ │ 16.7, │
│ │ 16.1, │
│ │ 18.9, │
│ │ 17.8 │
│ │ ] │
│ │ [ │
│ │ 20.0, │
│ │ 18.9, │
│ │ 17.2, │
│ │ 12.8, │
│ │ 13.3, │
│ │ 16.1, │
│ │ 16.1, │
│ │ 15.0, │
│ │ 17.2, │
│ │ 18.9, │
│ │ 23.3, │
│ │ 18.3, │
│ │ 16.1, │
│ │ 17.2, │
│ 2012-06-01 00:00:00 │ 22.2, │
│ │ 21.1, │
│ │ 18.9, │
│ │ 17.2, │
│ │ 19.4, │
│ │ 24.4, │
│ │ 23.9, │
│ │ 13.9, │
│ │ 15.6, │
│ │ 19.4, │
│ │ 19.4, │
│ │ 18.3, │
│ │ 22.8, │
│ │ 22.2, │
│ │ 21.7, │
│ │ 20.0 │
│ │ ] │
│ │ [ │
│ │ 20.0, │
│ │ 18.9, │
│ │ 18.3, │
│ │ 20.6, │
│ │ 24.4, │
│ │ 25.0, │
│ │ 26.7, │
│ │ 28.3, │
│ │ 25.0, │
│ │ 23.9, │
│ │ 27.8, │
│ │ 25.6, │
│ │ 23.3, │
│ │ 25.0, │
│ │ 18.9, │
│ 2012-07-01 00:00:00 │ 26.1, │
│ │ 21.7, │
│ │ 21.1, │
│ │ 25.0, │
│ │ 19.4, │
│ │ 23.9, │
│ │ 20.6, │
│ │ 18.9, │
│ │ 23.3, │
│ │ 26.7, │
│ │ 25.6, │
│ │ 18.9, │
│ │ 22.2, │
│ │ 22.8, │
│ │ 19.4, │
│ │ 22.8 │
│ │ ] │
│ │ [ │
│ │ 23.9, │
│ │ 23.3, │
│ │ 27.2, │
│ │ 33.9, │
│ │ 33.9, │
│ │ 28.3, │
│ │ 21.1, │
│ │ 22.2, │
│ │ 24.4, │
│ │ 25.6, │
│ │ 28.3, │
│ │ 30.6, │
│ │ 30.6, │
│ │ 28.9, │
│ │ 31.1, │
│ 2012-08-01 00:00:00 │ 34.4, │
│ │ 32.8, │
│ │ 21.7, │
│ │ 23.3, │
│ │ 25.6, │
│ │ 23.3, │
│ │ 22.2, │
│ │ 21.1, │
│ │ 22.2, │
│ │ 26.1, │
│ │ 21.1, │
│ │ 23.9, │
│ │ 22.8, │
│ │ 22.8, │
│ │ 22.8, │
│ │ 22.2 │
│ │ ] │
│ │ [ │
│ │ 21.7, │
│ │ 21.1, │
│ │ 22.8, │
│ │ 24.4, │
│ │ 26.1, │
│ │ 28.3, │
│ │ 32.2, │
│ │ 25.0, │
│ │ 18.9, │
│ │ 20.0, │
│ │ 20.0, │
│ │ 22.2, │
│ │ 27.8, │
│ │ 26.1, │
│ 2012-09-01 00:00:00 │ 22.2, │
│ │ 24.4, │
│ │ 27.8, │
│ │ 27.8, │
│ │ 23.9, │
│ │ 19.4, │
│ │ 16.1, │
│ │ 19.4, │
│ │ 19.4, │
│ │ 21.1, │
│ │ 19.4, │
│ │ 19.4, │
│ │ 22.8, │
│ │ 25.0, │
│ │ 20.6, │
│ │ 21.1 │
│ │ ] │
│ │ [ │
│ │ 23.3, │
│ │ 17.8, │
│ │ 18.9, │
│ │ 18.9, │
│ │ 21.7, │
│ │ 23.9, │
│ │ 23.9, │
│ │ 21.1, │
│ │ 16.1, │
│ │ 12.2, │
│ │ 13.9, │
│ │ 13.9, │
│ │ 15.6, │
│ │ 17.8, │
│ │ 17.2, │
│ 2012-10-01 00:00:00 │ 16.1, │
│ │ 14.4, │
│ │ 17.8, │
│ │ 15.0, │
│ │ 11.1, │
│ │ 11.7, │
│ │ 7.8, │
│ │ 11.1, │
│ │ 11.7, │
│ │ 11.7, │
│ │ 11.1, │
│ │ 14.4, │
│ │ 14.4, │
│ │ 15.6, │
│ │ 15.0, │
│ │ 15.6 │
│ │ ] │
│ … │ … │
└─────────────────────┴────────────────┘
Creating relations
In the context of a project, relations are created and managed automatically using the source generation process. In the context of a notebook or analysis, you can create relations from a variety of sources, including: - Pandas DataFrames - Polars DataFrames - PyArrow Tables - CSVs - JSONs - Parquet files For in-memory sources, useVinylTable.from_memory
as:
VinylTable.from_file
:
Exploring relations
In the properties section action, you’ve already seen some of the most common ways to visualize relations:print()
to view the AST.schema()
to view the schema.visualize()
to view the query plan.execute()
to run the query and view it as text, pyarrow, or pandas objects.to_sql()
to view the SQL-equivalent
.eda()
provides a quick exploratory data analysis of the relation,
excluding its most common values - .chart()
provides a grammar of
graphics interface to quickly visualize the relation
Let’s view examples of each of these:
┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┓
┃ name ┃ type ┃ nullable ┃ nulls ┃ non_nulls ┃ null_frac ┃ values ┃ counts ┃
┡━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━┩
│ string │ string │ boolean │ int64 │ int64 │ float64 │ array<string> │ array<int64> │
├───────────────┼──────────────┼──────────┼───────┼───────────┼───────────┼────────────────────────────────────────────────┼──────────────┤
│ date │ timestamp(6) │ True │ 0 │ 1461 │ 0.0 │ ['2012-02-05 00:00:00', '2012-02-14 00:00:00'] │ [1, 1] │
│ precipitation │ float64 │ True │ 0 │ 1461 │ 0.0 │ ['0.0', '0.3'] │ [838, 54] │
│ temp_max │ float64 │ True │ 0 │ 1461 │ 0.0 │ ['11.1', '14.4'] │ [58, 49] │
│ temp_min │ float64 │ True │ 0 │ 1461 │ 0.0 │ ['6.1', '10.0'] │ [66, 64] │
│ wind │ float64 │ True │ 0 │ 1461 │ 0.0 │ ['2.6', '3.0'] │ [76, 65] │
│ weather │ string │ True │ 0 │ 1461 │ 0.0 │ ['sun', 'fog'] │ [714, 411] │
└───────────────┴──────────────┴──────────┴───────┴───────────┴───────────┴────────────────────────────────────────────────┴──────────────┘
Charts made with Vinyl are interactive by default, but we turn that
feature off so our docs site can render them properly.