changed JSON Guide to use Books model

This commit is contained in:
Mark Burggraf committed 2021-06-30 15:12:59 -07:00
1 parent f30afa1f84
commit f36b81515b
1 file changed
+166 -240
+166 -240
View File
@@ -11,9 +11,9 @@ PostgreSQL supports [JSON functions and operators](https://www.postgresql.org/do
PostgreSQL supports two types of JSON columns: `JSON` and `JSONB`. The recommended type is `JSONB`, so that's what we'll be using throughout this document.
The `JSON` format stores data exactly as you enter it, so every time that data is used PostgreSQL has to reparse it in order to use it.
<!-- @TODO: I think we can explain this in our own words a bit more easily -->
> The json data type stores an exact copy of the input text, which processing functions must reparse on each execution; while jsonb data is stored in a decomposed binary format that makes it slightly slower to input due to added conversion overhead, but significantly faster to process, since no reparsing is needed. jsonb also supports indexing, which can be a significant advantage.
When you use the `JSONB` format, the data is parsed when it's put into the database so it's faster when querying and also it can be indexed, a big advantage!
From: [PostgreSQL JSON types](https://www.postgresql.org/docs/12/datatype-json.html)
@@ -22,79 +22,111 @@ From: [PostgreSQL JSON types](https://www.postgresql.org/docs/12/datatype-json.h
### Create a table with a JSON column.
<Tabs
defaultValue="UI"
defaultValue="Data"
values={[
{label: 'UI', value: 'UI'},
{label: 'Data', value: 'Data'},
{label: 'SQL', value: 'SQL'},
{label: 'UI', value: 'UI'},
]}>
<TabItem value="Data">
| id | title | author | metadata |
| -- | ----------------------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------- |
| 1 | The Poky Little Puppy | Janette Sebring Lowrey | {"ages":[3,6],"price":5.95,"description":"Puppy is slower than other, bigger animals."} |
| 2 | The Tale of Peter Rabbit | Beatrix Potter | {"ages":[2,5],"price":4.49,"description":"Rabbit eats some vegetables."} |
| 3 | Tootle | Gertrude Crampton | {"ages":[2,5],"price":3.99,"description":"Little toy train has big dreams."} |
| 4 | Green Eggs and Ham | Dr. Seuss | {"ages":[4,8],"price":7.49,"description":"Sam has changing food preferences and eats unusally colored food."} |
| 5 | Harry Potter and the Goblet of Fire | J.K. Rowling | {"ages":[10,99],"price":24.95,"description":"Fourth year of school starts, big drama ensues."} |
</TabItem>
<TabItem value="SQL">
```sql
CREATE TABLE books (
id SERIAL PRIMARY KEY,
title TEXT,
author TEXT,
metadata JSONB
);
```
</TabItem>
<TabItem value="UI">
```bash
1. Go to the Table Editor
- New Table
- Create a new table named `game_log`
- include primary key `id`, type `UUID`, default value `Automatically generate UUID`
- Create a new table named `books`
- include primary key `id`, type `int8`, default value `Automatically generate as indentity`
- Save the new table
- New Column
- Name the new column `game_data`
- Make it type `JSONB`
- `New Column`
- Name the new column `title`
- Make it type `text`
- Save the new column
- `New Column`
- Name the new column `author`
- Make it type `text`
- Save the new column
- `New Column`
- Name the new column `metadata`
- Make it type `jsonb`
- Save the new column
- Add the other columns used by this demo
- game_date type DATE
- home_team type TEXT
- visiting_team type TEXT
```
</TabItem>
<TabItem value="SQL">
```sql
CREATE TABLE game_log (
id UUID DEFAULT uuid_generate_v4() NOT NULL,
game_date DATE,
home_team TEXT,
visiting_team TEXT,
game_data JSONB
);
```
</TabItem>
</Tabs>
### Insert data into the table:
### Insert data into the table.
<Tabs
defaultValue="UI"
values={[
{label: 'Data', value: 'Data'},
{label: 'UI', value: 'UI'},
{label: 'SQL', value: 'SQL'},
{label: 'JS', value: 'JavaScript'},
]}>
<TabItem value="Data">
| id | title | author | metadata |
| -- | ----------------------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------- |
| 1 | The Poky Little Puppy | Janette Sebring Lowrey | {"ages":[3,6],"price":5.95,"description":"Puppy is slower than other, bigger animals."} |
| 2 | The Tale of Peter Rabbit | Beatrix Potter | {"ages":[2,5],"price":4.49,"description":"Rabbit eats some vegetables."} |
| 3 | Tootle | Gertrude Crampton | {"ages":[2,5],"price":3.99,"description":"Little toy train has big dreams."} |
| 4 | Green Eggs and Ham | Dr. Seuss | {"ages":[4,8],"price":7.49,"description":"Sam has changing food preferences and eats unusally colored food."} |
| 5 | Harry Potter and the Goblet of Fire | J.K. Rowling | {"ages":[10,99],"price":24.95,"description":"Fourth year of school starts, big drama ensues."} |
</TabItem>
<TabItem value="UI">
```bash
- Table Editor
- Select `game_log`
- Insert Row
- game_date: 2021-06-02
- home_team: 'Chicago Cubs'
- visiting_team: 'San Diego Padres'
- game_data: [COPY AND PASTE THE JSON BLOCK]
{
"winning_pitcher": "Alzolay",
"losing_pitcher": "Johnson",
"final_score": {
"visitors": {"runs": 1, "hits": 5, "errors": 2},
"home": {"runs": 6, "hits": 9, "errors": 0}
},
"innings": {
"visitors": [0,0,0,1,0,0,0,0,0],
"home": [0,0,0,1,2,0,3,0]}
}
- Save the new row
- click `Table Editor`
- click `books`
- click `+ Insert Row`
- `title`: `The Poky Little Puppy`
- `author`: 'Janette Sebring Lowrey'
- `metadata`: {"description":"Puppy is slower than other, bigger animals.","price":5.95,"ages":[3,6]}
- click `Save`
- click `+ Insert Row`
- `title`: `The Tale of Peter Rabbit`
- `author`: 'Beatrix Potter'
- `metadata`: {"ages":[2,5],"price":4.49,"description":"Rabbit eats some vegetables."}
- click `Save`
- click `+ Insert Row`
- `title`: `Tootle`
- `author`: 'Gertrude Crampton'
- `metadata`: {"ages":[2,5],"price":3.99,"description":"Little toy train has big dreams."}
- click `Save`
- click `+ Insert Row`
- `title`: `Green Eggs and Ham`
- `author`: 'Dr. Seuss'
- `metadata`: {"ages":[4,8],"price":7.49,"description":"Sam has changing food preferences and eats unusally colored food."}
- click `Save`
- click `+ Insert Row`
- `title`: `Harry Potter and the Goblet of Fire`
- `author`: 'J.K. Rowling'
- `metadata`: {"ages":[10,99],"price":24.95,"description":"Fourth year of school starts, big drama ensues."}
- click `Save`
```
</TabItem>
@@ -102,22 +134,22 @@ values={[
<TabItem value="SQL">
```sql
INSERT into game_log (game_date, home_team, visiting_team, game_data)
values (
'2021-06-02',
'Chicago Cubs',
'San Diego Padres',
'{"winning_pitcher": "Alzolay",
"losing_pitcher": "Johnson",
"final_score": {
"visitors": {"runs": 1, "hits": 5, "errors": 2},
"home": {"runs": 6, "hits": 9, "errors": 0}
},
"innings": {
"visitors": [0,0,0,1,0,0,0,0,0],
"home": [0,0,0,1,2,0,3,0]}
}'
);
insert into books (title, author, metadata) values
('The Poky Little Puppy',
'Janette Sebring Lowrey',
'{"description":"Puppy is slower than other, bigger animals.","price":5.95,"ages":[3,6]}'),
('The Tale of Peter Rabbit',
'Beatrix Potter',
'{"description":"Rabbit eats some vegetables.","price":4.49,"ages":[2,5]}'),
('Tootle',
'Gertrude Crampton',
'{"description":"Little toy train has big dreams.","price":3.99,"ages":[2,5]}'),
('Green Eggs and Ham',
'Dr. Seuss',
'{"description":"Sam has changing food preferences and eats unusally colored food.","price":7.49,"ages":[4,8]}'),
('Harry Potter and the Goblet of Fire',
'J.K. Rowling',
'{"description":"Fourth year of school starts, big drama ensues.","price":24.95,"ages":[10,99]}');
```
</TabItem>
@@ -125,24 +157,34 @@ values (
```js
const { data, error } = await supabase
.from('game_log')
.insert([{
game_date: '2021-06-02',
home_team: 'Chicago Cubs',
visiting_team: 'San Diego Padres',
game_data: {
"winning_pitcher": "Alzolay",
"losing_pitcher": "Johnson",
"final_score": {
"visitors": {"runs": 1, "hits": 5, "errors": 2},
"home": {"runs": 6, "hits": 9, "errors": 0}
},
"innings": {
"visitors": [0,0,0,1,0,0,0,0,0],
"home": [0,0,0,1,2,0,3,0]
}
}
}]);
.from('books')
.insert([
{
title: 'The Poky Little Puppy',
author: 'Janette Sebring Lowrey',
metadata: {"description":"Puppy is slower than other, bigger animals.","price":5.95,"ages":[3,6]}
},
{
title: 'The Tale of Peter Rabbit',
author: 'Beatrix Potter',
metadata: {"description":"Rabbit eats some vegetables.","price":4.49,"ages":[2,5]}
},
{
title: 'Tootle',
author: 'Gertrude Crampton',
metadata: {"description":"Little toy train has big dreams.","price":3.99,"ages":[2,5]}
},
{
title:'Green Eggs and Ham',
author:'Dr. Seuss',
metadata: {"description":"Sam has changing food preferences and eats unusally colored food.","price":7.49,"ages":[4,8]}
},
{
title:'Harry Potter and the Goblet of Fire',
author:'J.K. Rowling',
metadata: {"description":"Fourth year of school starts, big drama ensues.","price":24.95,"ages":[10,99]}
}
]);
```
</TabItem>
@@ -150,215 +192,99 @@ const { data, error } = await supabase
### View the data:
### View the data.
<Tabs
defaultValue="SQL"
values={[
{label: 'Data', value: 'Data'},
{label: 'SQL', value: 'SQL'},
{label: 'JS', value: 'JavaScript'},
]}>
<TabItem value="Data">
| id | title | author | metadata |
| -- | ----------------------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------- |
| 1 | The Poky Little Puppy | Janette Sebring Lowrey | {"ages":[3,6],"price":5.95,"description":"Puppy is slower than other, bigger animals."} |
| 2 | The Tale of Peter Rabbit | Beatrix Potter | {"ages":[2,5],"price":4.49,"description":"Rabbit eats some vegetables."} |
| 3 | Tootle | Gertrude Crampton | {"ages":[2,5],"price":3.99,"description":"Little toy train has big dreams."} |
| 4 | Green Eggs and Ham | Dr. Seuss | {"ages":[4,8],"price":7.49,"description":"Sam has changing food preferences and eats unusally colored food."} |
| 5 | Harry Potter and the Goblet of Fire | J.K. Rowling | {"ages":[10,99],"price":24.95,"description":"Fourth year of school starts, big drama ensues."} |
</TabItem>
<TabItem value="SQL">
```sql
SELECT * FROM game_log;
SELECT * FROM books;
```
Resuls:
| id | game_date | home_team | visiting_team | game_data |
| ------------------------------------ | ------------------------ | ------------ | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 24550f27-28d2-46f3-b577-aeede4614018 | 2021-06-02T00:00:00.000Z | Chicago Cubs | San Diego Padres | {"innings":{"home":[0,0,0,1,2,0,3,0],"visitors":[0,0,0,1,0,0,0,0,0]},"final_score":{"home":{"hits":9,"runs":6,"errors":0},"visitors":{"hits":5,"runs":1,"errors":2}},"losing_pitcher":"Johnson","winning_pitcher":"Alzolay"} |
</TabItem>
<TabItem value="JavaScript">
```js
const { data, error } = await supabase
.from('game_log')
.from('books')
.select('*');
console.log(JSON.stringify(data,null,2));
```
Results:
```js
[
{
"id": "a4c577bc-4343-440d-8f8b-9fef0af225cc",
"game_date": "2021-06-02",
"home_team": "Chicago Cubs",
"visiting_team": "San Diego Padres",
"game_data": {
"innings": {
"home": [0,0,0,1,2,0,3,0],
"visitors": [0,0,0,1,0,0,0,0,0]
},
"final_score": {
"home": {"hits": 9, "runs": 6, "errors": 0},
"visitors": {"hits": 5, "runs": 1, "errors": 2}
},
"losing_pitcher": "Johnson",
"winning_pitcher": "Alzolay"
}
}
]
console.log(JSON.stringify(data, null, 2));
```
</TabItem>
</Tabs>
### Select the winning pitcher from the JSONB field:
### Query the `JSONB` data.
#### Select title, description, price, and age range for each book.
<Tabs
defaultValue="SQL"
values={[
{label: 'SQL', value: 'SQL'},
{label: 'JS', value: 'JavaScript'},
{label: 'Results', value: 'Results'}
]}>
<TabItem value="SQL">
```sql
select game_data -> 'winning_pitcher' AS winning_pitcher
from game_log;
SELECT title,
metadata -> 'description' AS description,
metadata -> 'price' as price,
metadata -> 'ages' -> 0 as low_age,
metadata -> 'ages' -> 1 as high_age
FROM books;
```
Results:
| winning_pitcher |
| --------------- |
| Alzolay |
</TabItem>
<TabItem value="JavaScript">
```js
const { data, error } = await supabase
.from('game_log')
.select('game_data->winning_pitcher');
console.log(JSON.stringify(data,null,2));
.from('books')
.select('title,description:metadata->description,price:metadata->price,low_age:metadata->ages->0,high_age:metadata->ages->1');
console.log(JSON.stringify(data, null, 2));
```
Results:
</TabItem>
<TabItem value="Results">
```js
[
{
"winning_pitcher": "Alzolay"
}
]
```
| title | description | price | low_age | high_age |
| ----------------------------------- | ----------------------------------------------------------------- | ----- | ------- | -------- |
| The Poky Little Puppy | Puppy is slower than other, bigger animals. | 5.95 | 3 | 6 |
| The Tale of Peter Rabbit | Rabbit eats some vegetables. | 4.49 | 2 | 5 |
| Tootle | Little toy train has big dreams. | 3.99 | 2 | 5 |
| Green Eggs and Ham | Sam has changing food preferences and eats unusally colored food. | 7.49 | 4 | 8 |
| Harry Potter and the Goblet of Fire | Fourth year of school starts, big drama ensues. | 24.95 | 10 | 99 |
</TabItem>
</Tabs>
### Get the final scores:
<Tabs
defaultValue="SQL"
values={[
{label: 'SQL', value: 'SQL'},
{label: 'JS', value: 'JavaScript'},
]}>
<TabItem value="SQL">
```sql
select
visiting_team,
game_data -> 'final_score' -> 'visitors' -> 'runs' as visitors_runs,
home_team,
game_data -> 'final_score' -> 'home' -> 'runs' as home_runs
from game_log;
```
Results:
| visiting_team | visitors_runs | home_team | home_runs |
| ---------------- | ------------- | ------------ | --------- |
| San Diego Padres | 1 | Chicago Cubs | 6 |
</TabItem>
<TabItem value="JavaScript">
```js
const { data, error } = await supabase
.from('game_log')
.select('visiting_team, visitors_runs:game_data->final_score->visitors->runs, home_team, home_runs:game_data->final_score->home->runs');
console.log(JSON.stringify(data,null,2));
```
Results:
```js
[
{
"visiting_team": "San Diego Padres",
"visitors_runs": 1,
"home_team": "Chicago Cubs",
"home_runs": 6
}
]
```
</TabItem>
</Tabs>
### How many runs did the home team score in the 7th inning?
(Note that data is stored in a zero-based array, so to get data from the 7th inning, we use a 6.)
<Tabs
defaultValue="SQL"
values={[
{label: 'SQL', value: 'SQL'},
{label: 'JS', value: 'JavaScript'},
]}>
<TabItem value="SQL">
```sql
SELECT home_team,
game_data -> 'innings' -> 'home' -> 6 as seventh_inning
FROM game_log;
```
Results:
| home_team | seventh_inning |
| ------------ | -------------- |
| Chicago Cubs | 3 |
</TabItem>
<TabItem value="JavaScript">
```js
const { data, error } = await this.supabase
.from('game_log')
.select('home_team, seventh_inning_runs:game_data->innings->home->6');
console.log(JSON.stringify(data,null,2));
```
Results:
```js
[
{
"home_team": "Chicago Cubs",
"seventh_inning_runs": 3
}
]
```
</TabItem>
</Tabs>
#### Data Types
One last thing to note: the -> operator return JSONB data. If you want TEXT/STRING data returned, you need to use the ->> operator.
One last thing to note: the -> operator returns JSONB data. If you want TEXT/STRING data returned, you need to use the ->> operator.
- game_data -> 'winning_pitcher' (this returns a JSON object)
- game_data ->> 'winning_pitcher' (this returns STRING/TEXT data)
- metadata -> 'description' (this returns a JSON object)
- metadata ->> 'description' (this returns STRING/TEXT data)
## Resources