mirror of
https://github.com/supabase/supabase.git
synced 2026-10-14 21:59:16 +03:00
changed JSON Guide to use Books model
This commit is contained in:
1 parent
f30afa1f84
commit
f36b81515b
1 file changed
+166
-240
+166
-240
@@ -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
|
||||
|
||||
|
||||
Reference in new issue
Block a user