mirror of
https://github.com/supabase/supabase.git
synced 2026-10-08 19:05:06 +03:00
* Update the functions documentation for python lib * Apply suggestions from code review Co-authored-by: Copple <10214025+kiwicopple@users.noreply.github.com> --------- Co-authored-by: Copple <10214025+kiwicopple@users.noreply.github.com>
2034 lines
65 KiB
YAML
2034 lines
65 KiB
YAML
openref: 0.1
|
|
|
|
info:
|
|
id: reference/supabase-py
|
|
title: Supabase Python Client
|
|
description: |
|
|
|
|
Supabase Python(Community).
|
|
|
|
definition: ../../spec/enrichments/tsdoc_v2/combined.json
|
|
specUrl: https://github.com/supabase/supabase/edit/master/spec/supabase_py_v2.yml
|
|
slugPrefix: '/'
|
|
libraries:
|
|
- name: 'Python'
|
|
id: 'py'
|
|
version: '0.0.1'
|
|
|
|
functions:
|
|
- id: initializing
|
|
description: |
|
|
You can initialize a new Supabase client using the `create_client()` method.
|
|
|
|
The Supabase client is your entrypoint to the rest of the Supabase functionality
|
|
and is the easiest way to interact with everything we offer within the Supabase ecosystem.
|
|
|
|
examples:
|
|
- id: create-client
|
|
name: create_client()
|
|
code: |
|
|
```
|
|
import os
|
|
from supabase import create_client, Client
|
|
|
|
url: str = os.environ.get("SUPABASE_URL")
|
|
key: str = os.environ.get("SUPABASE_KEY")
|
|
supabase: Client = create_client(url, key)
|
|
```
|
|
- id: with-timeout-option
|
|
name: With timeout option
|
|
code: |
|
|
```
|
|
import os
|
|
from supabase import create_client, Client, ClientOptions
|
|
|
|
url: str = os.environ.get("SUPABASE_URL")
|
|
key: str = os.environ.get("SUPABASE_KEY")
|
|
supabase: Client = create_client(url, key,
|
|
options=ClientOptions(
|
|
postgrest_client_timeout=10,
|
|
storage_client_timeout=10
|
|
))
|
|
```
|
|
|
|
- id: sign-up
|
|
title: 'sign_up()'
|
|
notes: |
|
|
- By default, the user needs to verify their email address before logging in. To turn this off, disable **Confirm email** in [your project](https://supabase.com/dashboard/project/_/auth/providers).
|
|
- **Confirm email** determines if users need to confirm their email address after signing up.
|
|
- If **Confirm email** is enabled, a `user` is returned but `session` is null.
|
|
- If **Confirm email** is disabled, both a `user` and a `session` are returned.
|
|
- By default, when the user confirms their email address, they are redirected to the [`SITE_URL`](https://supabase.com/docs/reference/auth/config#site_url). You can modify your `SITE_URL` or add additional redirect URLs in [your project](https://supabase.com/dashboard/project/_/auth/url-configuration).
|
|
- If sign_up() is called for an existing confirmed user:
|
|
- If **Confirm email** is enabled in [your project](https://supabase.com/dashboard/project/_/auth/providers), an obfuscated/fake user object is returned.
|
|
- If **Confirm email** is disabled, the error message, `User already registered` is returned.
|
|
- To fetch the currently logged-in user, refer to [`getUser()`](/docs/reference/javascript/auth-getuser).
|
|
examples:
|
|
- id: signup
|
|
name: Sign up
|
|
code: |
|
|
```
|
|
res = supabase.auth.sign_up({
|
|
"email": 'example@email.com',
|
|
"password": 'example-password',
|
|
})
|
|
```
|
|
- id: sign-up-with-additional-user-metadata
|
|
name: Sign up with additional user metadata
|
|
code: |
|
|
```
|
|
res = supabase.auth.sign_up({
|
|
"email": 'example@email.com',
|
|
"password": 'example-password',
|
|
"options": {
|
|
"data": {
|
|
"first_name": 'John',
|
|
"age": 27,
|
|
}
|
|
}
|
|
})
|
|
```
|
|
- id: sign-in-with-password
|
|
title: 'sign_in_with_password'
|
|
notes: |
|
|
- Requires either an email and password or a phone number and password.
|
|
examples:
|
|
- id: sign-in-with-email-and-password
|
|
name: Sign in with email and password
|
|
isSpotlight: true
|
|
code: |
|
|
```
|
|
data = supabase.auth.sign_in_with_password({"email": "j0@supabase.io", "password": "testsupabasenow"})
|
|
```
|
|
- id: sign-in-with-phone-and-password
|
|
name: Sign in with phone and password
|
|
isSpotlight: false
|
|
code: |
|
|
```
|
|
data = supabase.auth.sign_in_with_password({"phone": "+1234566", password": "testsupabasenow"})
|
|
# After receiving a SMS with a OTP.
|
|
data = supabase.auth.verify_otp({
|
|
"phone": '+13334445555',
|
|
"token": '123456',
|
|
})
|
|
```
|
|
- id: sign-in-with-otp
|
|
title: 'sign_in_with_otp'
|
|
notes: |
|
|
- Requires either an email or phone number.
|
|
- This method is used for passwordless sign-ins where a OTP is sent to the user's email or phone number.
|
|
- If the user doesn't exist, `sign_in_with_otp()` will signup the user instead. To restrict this behavior, you can set `should_create_user` in `SignInWithPasswordlessCredentials.options` to `false`.
|
|
- If you're using an email, you can configure whether you want the user to receive a magiclink or a OTP.
|
|
- If you're using phone, you can configure whether you want the user to receive a OTP.
|
|
- The magic link's destination URL is determined by the [`SITE_URL`](/docs/reference/auth/config#site_url).
|
|
- See [redirect URLs and wildcards](/docs/guides/auth/overview#redirect-urls-and-wildcards) to add additional redirect URLs to your project.
|
|
- Magic links and OTPs share the same implementation. To send users a one-time code instead of a magic link, [modify the magic link email template](https://supabase.com/dashboard/project/_/auth/templates) to include `{{ .Token }}` instead of `{{ .ConfirmationURL }}`.
|
|
examples:
|
|
- id: sign-in-with-email
|
|
name: Sign in with email
|
|
isSpotlight: true
|
|
description: The user will be sent an email which contains either a magiclink or a OTP or both. By default, a given user can only request a OTP once every 60 seconds.
|
|
code: |
|
|
```
|
|
data = supabase.auth.sign_in_with_otp({
|
|
"email": 'example@email.com',
|
|
"options": {
|
|
"email_redirect_to": 'https://example.com/welcome'
|
|
}
|
|
})
|
|
```
|
|
- id: sign-in-with-sms-otp
|
|
name: Sign in with SMS OTP
|
|
isSpotlight: false
|
|
description: The user will be sent a SMS which contains a OTP. By default, a given user can only request a OTP once every 60 seconds.
|
|
code: |
|
|
```
|
|
data = supabase.auth.sign_in_with_otp({
|
|
phone: '+13334445555',
|
|
})
|
|
```
|
|
- id: sign-in-with-oauth
|
|
title: 'sign_in_with_oauth'
|
|
notes: |
|
|
- This method is used for signing in using a third-party provider.
|
|
- Supabase supports many different [third-party providers](https://supabase.com/docs/guides/auth#providers).
|
|
examples:
|
|
- id: sign-in-using-a-third-party-provider
|
|
name: Sign in using a third-party provider
|
|
isSpotlight: true
|
|
code: |
|
|
```
|
|
data = supabase.auth.sign_in_with_oauth({
|
|
"provider": 'github'
|
|
})
|
|
```
|
|
- id: sign-in-using-a-third-party-provider-with-redirect
|
|
name: Sign in using a third-party provider with redirect
|
|
isSpotlight: false
|
|
description: |
|
|
- When the third-party provider successfully authenticates the user, the provider redirects the user to the URL specified in the `redirectTo` parameter. This parameter defaults to the [`SITE_URL`](/docs/reference/auth/config#site_url). It does not redirect the user immediately after invoking this method.
|
|
- See [redirect URLs and wildcards](/docs/guides/auth/overview#redirect-urls-and-wildcards) to add additional redirect URLs to your project.
|
|
code: |
|
|
```
|
|
data = supabase.auth.sign_in_with_oauth({
|
|
"provider": 'github',
|
|
"options": {
|
|
"redirect_to": 'https://example.com/welcome'
|
|
}
|
|
})
|
|
```
|
|
- id: sign-in-with-scopes
|
|
name: Sign in with scopes
|
|
isSpotlight: false
|
|
description: |
|
|
If you need additional data from an OAuth provider, you can include a space-separated list of scopes in your request to get back an OAuth provider token.
|
|
You may also need to specify the scopes in the provider's OAuth app settings, depending on the provider. The list of scopes will be documented by the third-party provider you are using and specifying scopes will enable you to use the OAuth provider token to call additional APIs supported by the third-party provider to get more information.
|
|
code: |
|
|
```
|
|
data = supabase.auth.sign_in_with_oauth({
|
|
"provider": 'github',
|
|
"options": {
|
|
"scopes": 'repo gist notifications'
|
|
}
|
|
})
|
|
oauth_token = data.session.provider_token # use to access provider API
|
|
```
|
|
- id: sign-out
|
|
title: 'sign_out()'
|
|
notes: |
|
|
- In order to use the `signOut()` method, the user needs to be signed in first.
|
|
examples:
|
|
- id: sign-out
|
|
name: Sign out
|
|
code: |
|
|
```
|
|
res = supabase.auth.sign_out()
|
|
```
|
|
- id: verify-otp
|
|
title: 'verify_otp'
|
|
notes: |
|
|
- The `verify_otp` method takes in different verification types. If a phone number is used, the type can either be `sms` or `phone_change`. If an email address is used, the type can be one of the following: `signup`, `magiclink`, `recovery`, `invite` or `email_change`.
|
|
- The verification type used should be determined based on the corresponding auth method called before `verify_otp` to sign up / sign-in a user.
|
|
examples:
|
|
- id: verify-sms-one-time-password
|
|
name: Verify SMS One-Time Password (OTP)
|
|
code: |
|
|
```
|
|
res = supabase.auth.verify_otp(phone, token)
|
|
```
|
|
- id: get-user
|
|
title: 'get_user'
|
|
notes: |
|
|
- This method gets the user object from the current session.
|
|
- Fetches the user object from the database instead of local session.
|
|
examples:
|
|
- id: get-the-logged-in-user-with-the-current-existing-session
|
|
name: Get the logged in user with the current existing session
|
|
isSpotlight: true
|
|
code: |
|
|
```
|
|
data = supabase.auth.get_user()
|
|
```
|
|
- id: get-the-logged-in-user-with-a-custom-access-token-jwt
|
|
name: Get the logged in user with a custom access token jwt
|
|
isSpotlight: false
|
|
code: |
|
|
```
|
|
data = supabase.auth.get_user(jwt)
|
|
```
|
|
|
|
- id: get-session
|
|
title: 'get_session'
|
|
examples:
|
|
- id: get-session
|
|
name: Get the session data
|
|
code: |
|
|
```
|
|
res = supabase.auth.get_session()
|
|
```
|
|
|
|
- id: set-session
|
|
title: 'set_session()'
|
|
notes: |
|
|
- `setSession()` takes in a refresh token and uses it to get a new session.
|
|
- The refresh token can only be used once to obtain a new session.
|
|
- [Refresh token rotation](/docs/reference/auth/config#refresh_token_rotation_enabled) is enabled by default on all projects to guard against replay attacks.
|
|
- You can configure the [`REFRESH_TOKEN_REUSE_INTERVAL`](https://supabase.com/docs/reference/auth/config#refresh_token_reuse_interval) which provides a short window in which the same refresh token can be used multiple times in the event of concurrency or offline issues.
|
|
- If you are using React Native, you will need to install a Buffer polyfill via a library such as [rn-nodeify](https://github.com/tradle/rn-nodeify) to properly use the library.
|
|
examples:
|
|
- id: set-session
|
|
name: Refresh the session
|
|
description: Sets the session data from refresh_token and returns current session or an error if the refresh_token is invalid.
|
|
code: |
|
|
```
|
|
res = supabase.auth.set_session(access_token, refresh_token)
|
|
```
|
|
- id: refresh-session
|
|
title: 'refresh_session()'
|
|
notes: |
|
|
- This method will refresh the session whether the current one is expired or not.
|
|
- Both examples destructure `user` and `session` from `data`. This is not required; so `const { data, error } =` is also valid.
|
|
examples:
|
|
- id: refresh-session
|
|
name: Refresh session using the current session
|
|
code: |
|
|
```
|
|
res = supabase.auth.refresh_session()
|
|
```
|
|
- id: select
|
|
title: 'Fetch data: select()'
|
|
notes: |
|
|
- By default, Supabase projects return a maximum of 1,000 rows. This setting can be changed in your project's [API settings](https://supabase.com/dashboard/project/_/settings/api). It's recommended that you keep it low to limit the payload size of accidental or malicious requests.
|
|
- `apikey` is a reserved keyword if you're using the [Supabase Platform](/docs/guides/platform) and [should be avoided as a column name](https://github.com/supabase/supabase/issues/5465).
|
|
examples:
|
|
- id: getting-your-data
|
|
name: Getting your data
|
|
code: |
|
|
```python
|
|
response = supabase.table('countries').select("*").execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'Afghanistan'),
|
|
(2, 'Albania'),
|
|
(3, 'Algeria');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'id': 1, 'name': 'Afghanistan'},
|
|
{'id': 2, 'name': 'Albania'},
|
|
{'id': 3, 'name': 'Algeria'}],
|
|
count=None)
|
|
```
|
|
- id: selecting-specific-columns
|
|
name: Selecting specific columns
|
|
code: |
|
|
```
|
|
response = supabase.table('countries').select('name').execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'Afghanistan'),
|
|
(2, 'Albania'),
|
|
(3, 'Algeria');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'name': 'Afghanistan'},
|
|
{'name': 'Albania'},
|
|
{'name': 'Algeria'}],
|
|
count=None)
|
|
```
|
|
- id: query-foreign-tables
|
|
name: Query foreign tables
|
|
description: |
|
|
If your database has foreign key relationships, you can query related tables too.
|
|
code: |
|
|
```
|
|
response = supabase.table('countries')
|
|
.select('name, cities(name)')
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
create table
|
|
cities (
|
|
id int8 primary key,
|
|
country_id int8 not null references countries,
|
|
name text
|
|
);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'Germany'),
|
|
(2, 'Indonesia');
|
|
insert into
|
|
cities (id, country_id, name)
|
|
values
|
|
(1, 2, 'Bali'),
|
|
(2, 1, 'Munich');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'name': 'Germany', 'cities': [{'name': 'Munich'}]},
|
|
{'name': 'Indonesia', 'cities': [{'name': 'Bali'}]}],
|
|
count=None)
|
|
```
|
|
- id: query-foreign-tables-through-a-join-table
|
|
name: Query foreign tables through a join table
|
|
code: |
|
|
```
|
|
response = supabase.table('users')
|
|
.select('name, teams(name)')
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
users (
|
|
id int8 primary key,
|
|
name text
|
|
);
|
|
create table
|
|
teams (
|
|
id int8 primary key,
|
|
name text
|
|
);
|
|
-- join table
|
|
create table
|
|
users_teams (
|
|
user_id int8 not null references users,
|
|
team_id int8 not null references teams,
|
|
-- both foreign keys must be part of a composite primary key
|
|
primary key (user_id, team_id)
|
|
);
|
|
|
|
insert into
|
|
users (id, name)
|
|
values
|
|
(1, 'Kiran'),
|
|
(2, 'Evan');
|
|
insert into
|
|
teams (id, name)
|
|
values
|
|
(1, 'Green'),
|
|
(2, 'Blue');
|
|
insert into
|
|
users_teams (user_id, team_id)
|
|
values
|
|
(1, 1),
|
|
(1, 2),
|
|
(2, 2);
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[
|
|
{'name': 'Kiran', 'teams': [{'name': 'Green'}, {'name': 'Blue'}]},
|
|
{'name': 'Evan', 'teams': [{'name': 'Blue'}]}
|
|
],
|
|
count=None)
|
|
```
|
|
description: |
|
|
If you're in a situation where your tables are **NOT** directly
|
|
related, but instead are joined by a _join table_, you can still use
|
|
the `select()` method to query the related data. The join table needs
|
|
to have the foreign keys as part of its composite primary key.
|
|
hideCodeBlock: true
|
|
- id: query-the-same-foreign-table-multiple-times
|
|
name: Query the same foreign table multiple times
|
|
code: |
|
|
```
|
|
response = supabase.table('messages')
|
|
.select('content,from:sender_id(name),to:receiver_id(name)')
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
users (id int8 primary key, name text);
|
|
|
|
create table
|
|
messages (
|
|
sender_id int8 not null references users,
|
|
receiver_id int8 not null references users,
|
|
content text
|
|
);
|
|
|
|
insert into
|
|
users (id, name)
|
|
values
|
|
(1, 'Kiran'),
|
|
(2, 'Evan');
|
|
|
|
insert into
|
|
messages (sender_id, receiver_id, content)
|
|
values
|
|
(1, 2, '👋');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'content': '👋',
|
|
'from': {'name': 'Kiran'},
|
|
'to': {'name': 'Evan'}}
|
|
],
|
|
count=None)
|
|
```
|
|
description: |
|
|
If you need to query the same foreign table twice, use the name of the
|
|
joined column to identify which join to use. You can also give each
|
|
column an alias.
|
|
hideCodeBlock: true
|
|
- id: filtering-through-foreign-tables
|
|
name: Filtering through foreign tables
|
|
code: |
|
|
```
|
|
response = supabase.table('cities')
|
|
.select('name, countries(*)')
|
|
.eq('countries.name', 'Estonia')
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
create table
|
|
cities (
|
|
id int8 primary key,
|
|
country_id int8 not null references countries,
|
|
name text
|
|
);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'Germany'),
|
|
(2, 'Indonesia');
|
|
insert into
|
|
cities (id, country_id, name)
|
|
values
|
|
(1, 2, 'Bali'),
|
|
(2, 1, 'Munich');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'name': 'Bali', 'countries': None},
|
|
{'name': 'Munich', 'countries': None}],
|
|
count=None)
|
|
```
|
|
description: |
|
|
NOT WORKING CURRENTLY
|
|
If the filter on a foreign table's column is not satisfied, the foreign
|
|
table returns `[]` or `null` but the parent table is not filtered out.
|
|
If you want to filter out the parent table rows, use the `!inner` hint
|
|
hideCodeBlock: true
|
|
- id: querying-foreign-table-with-count
|
|
name: Querying foreign table with count
|
|
code: |
|
|
```
|
|
response = supabase.table('countries')
|
|
.select('*, cities(count)')
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table countries (
|
|
"id" "uuid" primary key default "extensions"."uuid_generate_v4"() not null,
|
|
"name" text
|
|
);
|
|
|
|
create table cities (
|
|
"id" "uuid" primary key default "extensions"."uuid_generate_v4"() not null,
|
|
"name" text,
|
|
"country_id" "uuid" references public.countries on delete cascade
|
|
);
|
|
|
|
with country as (
|
|
insert into countries (name)
|
|
values ('united kingdom') returning id
|
|
)
|
|
insert into cities (name, country_id) values
|
|
('London', (select id from country)),
|
|
('Manchester', (select id from country)),
|
|
('Liverpool', (select id from country)),
|
|
('Bristol', (select id from country));
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'id': 1, 'name': 'Germany', 'cities': [{'count': 1}]},
|
|
{'id': 2, 'name': 'Indonesia', 'cities': [{'count': 1}]}],
|
|
count=None)
|
|
```
|
|
description: |
|
|
You can get the number of rows in a related table by using the
|
|
**count** property.
|
|
hideCodeBlock: true
|
|
- id: querying-with-count-option
|
|
name: Querying with count option
|
|
code: |
|
|
```
|
|
response = supabase.table('countries')
|
|
.select('*', count='exact')
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'Afghanistan'),
|
|
(2, 'Albania'),
|
|
(3, 'Algeria');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'id': 1, 'name': 'Germany'},
|
|
{'id': 2, 'name': 'Indonesia'}],
|
|
count=2)
|
|
```
|
|
description: |
|
|
You can get the number of rows by using the
|
|
*count* parameter in the select query.
|
|
hideCodeBlock: true
|
|
- id: querying-json-data
|
|
name: Querying JSON data
|
|
code: |
|
|
```
|
|
response = supabase.table('users')
|
|
.select('id, name, address->city')
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
users (
|
|
id int8 primary key,
|
|
name text,
|
|
address jsonb
|
|
);
|
|
|
|
insert into
|
|
users (id, name, address)
|
|
values
|
|
(1, 'Avdotya', '{"city":"Saint Petersburg"}');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'id': 1, 'name': 'Avdotya', 'city': 'Saint Petersburg'}], count=None)
|
|
```
|
|
description: |
|
|
You can select and filter data inside of
|
|
[JSON](/docs/guides/database/json) columns. Postgres offers some
|
|
[operators](/docs/guides/database/json#query-the-jsonb-data) for
|
|
querying JSON data.
|
|
hideCodeBlock: true
|
|
|
|
- id: insert
|
|
title: 'Create data: insert()'
|
|
examples:
|
|
- id: create-a-record
|
|
name: Create a record
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('countries')
|
|
.insert({"id": 1, "name": "Denmark"})
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'id': 1, 'name': 'Denmark'}], count=None)
|
|
```
|
|
hideCodeBlock: true
|
|
isSpotlight: true
|
|
- id: update
|
|
title: 'Modify data: update()'
|
|
notes: |
|
|
- `update()` should always be combined with [Filters](/docs/reference/python/using-filters) to target the item(s) you wish to update.
|
|
examples:
|
|
- id: updating-your-data
|
|
name: Updating your data
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('countries')
|
|
.update({'name': 'Austrailia'})
|
|
.eq('id', 1)
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'Denmark');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'id': 1, 'name': 'Austrailia'}], count=None)
|
|
```
|
|
hideCodeBlock: true
|
|
isSpotlight: true
|
|
- id: upsert
|
|
title: 'Upsert data: upsert()'
|
|
notes: |
|
|
- Primary keys must be included in the `values` dict to use upsert.
|
|
examples:
|
|
- id: upsert-your-data
|
|
name: Upsert your data
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('countries')
|
|
.upsert({'id': 1, 'name': 'Austrailia'})
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'Afghanistan');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'id': 1, 'name': 'Austrailia'}], count=None)
|
|
```
|
|
hideCodeBlock: true
|
|
isSpotlight: true
|
|
- id: bulk-upsert-your-data
|
|
name: Bulk Upsert your data
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('countries')
|
|
.upsert([{'id': 1, 'name': 'Albania'}, {'id': 2, 'name': 'Algeria'}])
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'Afghanistan');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'id': 1, 'name': 'Albania'}, {'id': 2, 'name': 'Algeria'}], count=None)
|
|
```
|
|
hideCodeBlock: true
|
|
|
|
- id: delete
|
|
title: 'Delete data: delete()'
|
|
notes: |
|
|
- `delete()` should always be combined with [filters](/docs/reference/python/using-filters) to target the item(s) you wish to delete.
|
|
- If you use `delete()` with filters and you have
|
|
[RLS](/docs/learn/auth-deep-dive/auth-row-level-security) enabled, only
|
|
rows visible through `SELECT` policies are deleted. Note that by default
|
|
no rows are visible, so you need at least one `SELECT`/`ALL` policy that
|
|
makes the rows visible.
|
|
examples:
|
|
- id: delete-records
|
|
name: Delete records
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('countries')
|
|
.delete()
|
|
.eq('id', 1)
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'Spain');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'id': 1, 'name': 'United States'], count=None)
|
|
```
|
|
hideCodeBlock: true
|
|
isSpotlight: true
|
|
|
|
- id: using-filters
|
|
title: Using Filters
|
|
description: |
|
|
Filters allow you to only return rows that match certain conditions.
|
|
|
|
Filters can be used on `select()`, `update()`, `upsert()`, and `delete()` queries.
|
|
|
|
If a Postgres function returns a table response, you can also apply filters.
|
|
examples:
|
|
- id: applying-filters
|
|
name: Applying Filters
|
|
description: |
|
|
Filters must be applied after any of `select()`, `update()`, `upsert()`,
|
|
`delete()`, and `rpc()` and before
|
|
[modifiers](/docs/reference/python/using-modifiers).
|
|
code: |
|
|
```python
|
|
# Correct
|
|
data, count = supabase.from('cities')
|
|
.select('name, country_id')
|
|
.eq('name', 'The Shire')
|
|
.execute()
|
|
|
|
# Incorrect
|
|
data, count = supabase.table('cities')
|
|
.eq('name', 'The Shire')
|
|
.select('name, country_id')
|
|
.execute()
|
|
```
|
|
- id: chaining-filters
|
|
name: Chaining
|
|
description: |
|
|
Filters can be chained together to produce advanced queries. For example,
|
|
to query cities with population between 1,000 and 10,000.
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('cities')
|
|
.select('name, country_id')
|
|
.gte('population', 1000)
|
|
.lt('population', 10000)
|
|
.execute()
|
|
```
|
|
- id: conditional-chaining
|
|
name: Conditional chaining
|
|
description: |
|
|
Filters can be built up one step at a time and then executed.
|
|
code: |
|
|
```python
|
|
filterByName = None
|
|
filterPopLow = 1000
|
|
filterPopHigh = 10000
|
|
|
|
query = supabase.from('cities').select('name, country_id')
|
|
|
|
if filterByName:
|
|
query = query.eq('name', filterByName)
|
|
|
|
if filterPopLow:
|
|
query = query.gte('population', filterPopLow)
|
|
|
|
if filterPopHigh:
|
|
query = query.lt('population', filterPopHigh)
|
|
|
|
response = query.execute()
|
|
```
|
|
- id: filter-by-value-within-json-column
|
|
name: Filter by values within JSON column
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('users')
|
|
.select('*')
|
|
.eq('address->postcode', 90210)
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
users (
|
|
id int8 primary key,
|
|
name text,
|
|
address jsonb
|
|
);
|
|
|
|
insert into
|
|
users (id, name, address)
|
|
values
|
|
(1, 'Michael', '{ "postcode": 90210 }'),
|
|
(2, 'Jane', null);
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'id': 1, 'name': 'Michael', 'address': {'postcode': 90210}}], count=None)
|
|
```
|
|
- id: filter-foreign-tables
|
|
name: Filter Foreign Tables
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('countries')
|
|
.select('name, cities!inner(name)')
|
|
.eq('cities.name', 'Bali')
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
create table
|
|
cities (
|
|
id int8 primary key,
|
|
country_id int8 not null references countries,
|
|
name text
|
|
);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'Germany'),
|
|
(2, 'Indonesia');
|
|
insert into
|
|
cities (id, country_id, name)
|
|
values
|
|
(1, 2, 'Bali'),
|
|
(2, 1, 'Munich');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'name': 'Indonesia', 'cities': [{'name': 'Bali'}]}], count=None)
|
|
```
|
|
description: |
|
|
You can filter on foreign tables in your `select()` query using dot
|
|
notation.
|
|
|
|
- id: eq
|
|
title: eq()
|
|
examples:
|
|
- id: with-select
|
|
name: With `select()`
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('countries')
|
|
.select('*')
|
|
.eq('name', 'Albania')
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'Afghanistan'),
|
|
(2, 'Albania'),
|
|
(3, 'Algeria');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'id': 2, 'name': 'Albania'}], count=None)
|
|
```
|
|
hideCodeBlock: true
|
|
isSpotlight: true
|
|
- id: neq
|
|
title: neq()
|
|
examples:
|
|
- id: with-select
|
|
name: With `select()`
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('countries')
|
|
.select('*')
|
|
.neq('name', 'Albania')
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'Afghanistan'),
|
|
(2, 'Albania'),
|
|
(3, 'Algeria');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'id': 1, 'name': 'Afghanistan'},
|
|
{'id': 3, 'name': 'Algeria'}],
|
|
count=None)
|
|
```
|
|
hideCodeBlock: true
|
|
isSpotlight: true
|
|
- id: gt
|
|
title: gt()
|
|
examples:
|
|
- id: with-select
|
|
name: With `select()`
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('countries')
|
|
.select('*')
|
|
.gt('id', 2)
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'Afghanistan'),
|
|
(2, 'Albania'),
|
|
(3, 'Algeria');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'id': 3, 'name': 'Algeria'}], count=None)
|
|
```
|
|
hideCodeBlock: true
|
|
isSpotlight: true
|
|
description: |
|
|
When using [reserved words](https://www.postgresql.org/docs/current/sql-keywords-appendix.html) for column names you need
|
|
to add double quotes e.g. `.gt('"order"', 2)`
|
|
- id: gte
|
|
title: gte()
|
|
examples:
|
|
- id: with-select
|
|
name: With `select()`
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('countries')
|
|
.select('*')
|
|
.gte('id', 2)
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'Afghanistan'),
|
|
(2, 'Albania'),
|
|
(3, 'Algeria');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'id': 2, 'name': 'Albania'},
|
|
{'id': 3, 'name': 'Algeria'}],
|
|
count=None)
|
|
```
|
|
hideCodeBlock: true
|
|
isSpotlight: true
|
|
- id: lt
|
|
title: lt()
|
|
examples:
|
|
- id: with-select
|
|
name: With `select()`
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('countries')
|
|
.select('*')
|
|
.lt('id', 2)
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'Afghanistan'),
|
|
(2, 'Albania'),
|
|
(3, 'Algeria');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'id': 1, 'name': 'Afghanistan'}], count=None)
|
|
```
|
|
hideCodeBlock: true
|
|
isSpotlight: true
|
|
- id: lte
|
|
title: lte()
|
|
examples:
|
|
- id: with-select
|
|
name: With `select()`
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('countries')
|
|
.select('*')
|
|
.lte('id', 2)
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'Afghanistan'),
|
|
(2, 'Albania'),
|
|
(3, 'Algeria');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'id': 1, 'name': 'Afghanistan'},
|
|
{'id': 2, 'name': 'Albania'}],
|
|
count=None)
|
|
```
|
|
hideCodeBlock: true
|
|
isSpotlight: true
|
|
- id: like
|
|
title: like()
|
|
examples:
|
|
- id: with-select
|
|
name: With `select()`
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('countries')
|
|
.select('*')
|
|
.like('name', '%Alba%')
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'Afghanistan'),
|
|
(2, 'Albania'),
|
|
(3, 'Algeria');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'id': 2, 'name': 'Albania'}], count=None)
|
|
```
|
|
hideCodeBlock: true
|
|
isSpotlight: true
|
|
- id: ilike
|
|
title: ilike()
|
|
examples:
|
|
- id: with-select
|
|
name: With `select()`
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('countries')
|
|
.select('*')
|
|
.ilike('name', '%alba%')
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'Afghanistan'),
|
|
(2, 'Albania'),
|
|
(3, 'Algeria');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'id': 2, 'name': 'Albania'}], count=None)
|
|
```
|
|
hideCodeBlock: true
|
|
isSpotlight: true
|
|
- id: is
|
|
title: is_()
|
|
examples:
|
|
- id: checking-nullness
|
|
name: Checking for nullness, True or False
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('countries')
|
|
.select('*')
|
|
.is_('name', 'null')
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'Germany'),
|
|
(2, null);
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'id': 2, 'name': None}], count=None)
|
|
```
|
|
description: |
|
|
Using the `eq()` filter doesn't work when filtering for `null`. Instead, you need to use `is_()`.
|
|
|
|
To query for null values in python use the string 'null' instead of the python `None` value.
|
|
|
|
Note that `is` is a reserved word in Python, so the underscore is added to avoid a syntax error.
|
|
hideCodeBlock: true
|
|
isSpotlight: true
|
|
- id: in
|
|
title: in_()
|
|
examples:
|
|
- id: with-select
|
|
name: With `select()`
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('countries')
|
|
.select('*')
|
|
.in_('name', ['Albania', 'Algeria'])
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'Afghanistan'),
|
|
(2, 'Albania'),
|
|
(3, 'Algeria');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'id': 2, 'name': 'Albania'},
|
|
{'id': 3, 'name': 'Algeria'}],
|
|
count=None)
|
|
```
|
|
hideCodeBlock: true
|
|
isSpotlight: true
|
|
- id: contains
|
|
title: contains()
|
|
examples:
|
|
- id: on-array-columns
|
|
name: On array columns
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('issues')
|
|
.select('*')
|
|
.contains('tags', ['is:open', 'priority:low'])
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
users (
|
|
id int8 primary key,
|
|
name text,
|
|
tags text[]
|
|
);
|
|
insert into
|
|
issues (id, title, tags)
|
|
values
|
|
(1, 'Cache invalidation is not working', array['is:open', 'severity:high', 'priority:low']),
|
|
(2, 'Use better names', array['is:open', 'severity:low', 'priority:medium']);
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'id': 1, 'title': 'Cache invalidation is not working', 'tags': ['is:open', 'severity:high', 'priority:low']}], count=None)
|
|
```
|
|
hideCodeBlock: true
|
|
isSpotlight: true
|
|
- id: on-range-columns
|
|
name: On range columns
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('reservations')
|
|
.select('*')
|
|
.contains('during', '[2000-01-01 13:00, 2000-01-01 13:30)')
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
reservations (
|
|
id int8 primary key,
|
|
room_name text,
|
|
during tsrange
|
|
);
|
|
|
|
insert into
|
|
reservations (id, room_name, during)
|
|
values
|
|
(1, 'Emerald', '[2000-01-01 13:00, 2000-01-01 15:00)'),
|
|
(2, 'Topaz', '[2000-01-02 09:00, 2000-01-02 10:00)');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'id': 1, 'room_name': 'Emerald', 'during': '["2000-01-01 13:00:00","2000-01-01 15:00:00")'}], count=None)
|
|
```
|
|
description: |
|
|
Postgres supports a number of [range
|
|
types](https://www.postgresql.org/docs/current/rangetypes.html). You
|
|
can filter on range columns using the string representation of range
|
|
values.
|
|
hideCodeBlock: true
|
|
- id: on-jsonb-columns
|
|
name: On `jsonb` columns
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('users')
|
|
.select('*')
|
|
.contains('address', {'postcode': 90210})
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
users (
|
|
id int8 primary key,
|
|
name text,
|
|
address jsonb
|
|
);
|
|
|
|
insert into
|
|
users (id, name, address)
|
|
values
|
|
(1, 'Michael', '{ "postcode": 90210, "street": "Melrose Place" }'),
|
|
(2, 'Jane', '{}');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'id': 1, 'name': 'Michael', 'address': {'postcode': 90210}}], count=None)
|
|
```
|
|
hideCodeBlock: true
|
|
- id: contained-by
|
|
title: contained_by()
|
|
examples:
|
|
- id: on-array-columns
|
|
name: On array columns
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('classes')
|
|
.select('name')
|
|
.contained_by('days', ['monday', 'tuesday', 'wednesday', 'friday'])
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
classes (
|
|
id int8 primary key,
|
|
name text,
|
|
days text[]
|
|
);
|
|
|
|
insert into
|
|
classes (id, name, days)
|
|
values
|
|
(1, 'Chemistry', array['monday', 'friday']),
|
|
(2, 'History', array['monday', 'wednesday', 'thursday']);
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'name': 'Chemistry'}], count=None)
|
|
```
|
|
hideCodeBlock: true
|
|
isSpotlight: true
|
|
- id: on-range-columns
|
|
name: On range columns
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('reservations')
|
|
.select('*')
|
|
.contained_by('during', '[2000-01-01 00:00, 2000-01-01 23:59)')
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
reservations (
|
|
id int8 primary key,
|
|
room_name text,
|
|
during tsrange
|
|
);
|
|
|
|
insert into
|
|
reservations (id, room_name, during)
|
|
values
|
|
(1, 'Emerald', '[2000-01-01 13:00, 2000-01-01 15:00)'),
|
|
(2, 'Topaz', '[2000-01-02 09:00, 2000-01-02 10:00)');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'id': 1, 'room_name': 'Emerald', 'during': '["2000-01-01 13:00:00","2000-01-01 15:00:00")'}], count=None)
|
|
```
|
|
description: |
|
|
Postgres supports a number of [range
|
|
types](https://www.postgresql.org/docs/current/rangetypes.html). You
|
|
can filter on range columns using the string representation of range
|
|
values.
|
|
hideCodeBlock: true
|
|
- id: on-jsonb-columns
|
|
name: On `jsonb` columns
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('users')
|
|
.select('name')
|
|
.contained_by('address', {})
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
users (
|
|
id int8 primary key,
|
|
name text,
|
|
address jsonb
|
|
);
|
|
|
|
insert into
|
|
users (id, name, address)
|
|
values
|
|
(1, 'Michael', '{ "postcode": 90210, "street": "Melrose Place" }'),
|
|
(2, 'Jane', '{}');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'name': 'Jane'}], count=None)
|
|
```
|
|
hideCodeBlock: true
|
|
- id: match
|
|
title: match()
|
|
examples:
|
|
- id: with-select
|
|
name: With `select()`
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('countries')
|
|
.select('*')
|
|
.match({'id': 2, 'name': 'Albania'})
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'Afghanistan'),
|
|
(2, 'Albania'),
|
|
(3, 'Algeria');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'id': 2, 'name': 'Albania'}], count=None)
|
|
```
|
|
hideCodeBlock: true
|
|
isSpotlight: true
|
|
- id: not
|
|
title: not_()
|
|
examples:
|
|
- id: with-select
|
|
name: With `select()`
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('countries')
|
|
.select('*')
|
|
.not_.is_('name', 'null')
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'Albania'),
|
|
(2, null);
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'id': 2, 'name': 'Albania'}], count=None)
|
|
```
|
|
hideCodeBlock: true
|
|
isSpotlight: true
|
|
- id: filter
|
|
title: filter()
|
|
notes: |
|
|
filter() expects you to use the raw PostgREST syntax for the filter values.
|
|
examples:
|
|
- id: with-select
|
|
name: With `select()`
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('countries')
|
|
.select('*')
|
|
.filter('name', 'in', '("Algeria","Japan")')
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'Afghanistan'),
|
|
(2, 'Albania'),
|
|
(3, 'Algeria');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'id': 3, 'name': 'Algeria'}], count=None)
|
|
```
|
|
hideCodeBlock: true
|
|
isSpotlight: true
|
|
- id: on-a-foreign-table
|
|
name: On a foreign table
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('countries')
|
|
.select('name, cities!inner (name)')
|
|
.filter('cities.name', 'eq', 'Bali')
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
create table
|
|
cities (
|
|
id int8 primary key,
|
|
country_id int8 not null references countries,
|
|
name text
|
|
);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'Germany'),
|
|
(2, 'Indonesia');
|
|
insert into
|
|
cities (id, country_id, name)
|
|
values
|
|
(1, 2, 'Bali'),
|
|
(2, 1, 'Munich');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'name': 'Indonesia', 'cities': [{'name': 'Bali'}]}], count=None)
|
|
```
|
|
hideCodeBlock: true
|
|
|
|
- id: using-modifiers
|
|
title: Using Modifiers
|
|
description: |
|
|
Filters work on the row level—they allow you to return rows that
|
|
only match certain conditions without changing the shape of the rows.
|
|
Modifiers are everything that don't fit that definition—allowing you to
|
|
change the format of the response (e.g., returning a CSV string).
|
|
|
|
Modifiers must be specified after filters. Some modifiers only apply for
|
|
queries that return rows (e.g., `select()` or `rpc()` on a function that
|
|
returns a table response).
|
|
|
|
- id: order
|
|
title: order()
|
|
examples:
|
|
- id: with-select
|
|
name: With `select()`
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('countries')
|
|
.select('*')
|
|
.order('name', desc=True)
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'Afghanistan'),
|
|
(2, 'Albania'),
|
|
(3, 'Algeria');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(
|
|
data=[
|
|
{'id': 1, 'name': None},
|
|
{'id': 3, 'name': 'Algeria'},
|
|
{'id': 2, 'name': 'Albania'}],
|
|
count=None
|
|
)
|
|
```
|
|
hideCodeBlock: true
|
|
isSpotlight: true
|
|
- id: on-a-foreign-table
|
|
name: On a foreign table
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('countries')
|
|
.select('name, cities(name)')
|
|
.order('name', desc=True, foreign_table='cities')
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
create table
|
|
cities (
|
|
id int8 primary key,
|
|
country_id int8 not null references countries,
|
|
name text
|
|
);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'United States'),
|
|
(2, 'Vanuatu');
|
|
insert into
|
|
cities (id, country_id, name)
|
|
values
|
|
(1, 1, 'Atlanta'),
|
|
(2, 1, 'New York City');
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'name': 'United States', 'cities': [{'name': 'New York City'}, {'name': 'Atlanta'}]}, {'name': 'Vanuatu', 'cities': []}], count=None)
|
|
```
|
|
description: |
|
|
Ordering on foreign tables doesn't affect the ordering of
|
|
the parent table.
|
|
hideCodeBlock: true
|
|
- id: limit
|
|
title: limit()
|
|
examples:
|
|
- id: with-select
|
|
name: With `select()`
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('countries')
|
|
.select('*')
|
|
.limit(1)
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'Afghanistan'),
|
|
(2, 'Albania'),
|
|
(3, 'Algeria');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'id': 1, 'name': 'Afghanistan'}], count=None)
|
|
```
|
|
hideCodeBlock: true
|
|
isSpotlight: true
|
|
- id: on-a-foreign-table
|
|
name: On a foreign table
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('countries')
|
|
.select('name, cities(name)')
|
|
.limit(1, foreign_table='cities')
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
create table
|
|
cities (
|
|
id int8 primary key,
|
|
country_id int8 not null references countries,
|
|
name text
|
|
);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'United States');
|
|
insert into
|
|
cities (id, country_id, name)
|
|
values
|
|
(1, 1, 'Atlanta'),
|
|
(2, 1, 'New York City');
|
|
```
|
|
response: |
|
|
```
|
|
APIResponse(data=[{'name': 'United States', 'cities': [{'name': 'Atlanta'}]}], count=None)
|
|
```
|
|
hideCodeBlock: true
|
|
- id: single
|
|
title: single()
|
|
examples:
|
|
- id: with-select()
|
|
name: With `select()`
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('countries')
|
|
.select('name')
|
|
.limit(1)
|
|
.single()
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'Afghanistan'),
|
|
(2, 'Albania'),
|
|
(3, 'Algeria');
|
|
```
|
|
response: |
|
|
```
|
|
SingleAPIResponse(data={'name': 'Afghanistan'}, count=None)
|
|
```
|
|
hideCodeBlock: true
|
|
isSpotlight: true
|
|
- id: maybe-single
|
|
title: maybe_single()
|
|
examples:
|
|
- id: with-select
|
|
name: With `select()`
|
|
code: |
|
|
```python
|
|
data, count = supabase.table('countries')
|
|
.select('*')
|
|
.eq('name', 'Albania')
|
|
.maybe_single()
|
|
.execute()
|
|
```
|
|
data:
|
|
sql: |
|
|
```sql
|
|
create table
|
|
countries (id int8 primary key, name text);
|
|
|
|
insert into
|
|
countries (id, name)
|
|
values
|
|
(1, 'Afghanistan'),
|
|
(2, 'Albania'),
|
|
(3, 'Algeria');
|
|
```
|
|
response: |
|
|
```
|
|
SingleAPIResponse(data={'id': 2, 'name': 'Albania'}, count=None)
|
|
```
|
|
hideCodeBlock: true
|
|
isSpotlight: true
|
|
|
|
- id: invoke
|
|
title: 'invoke()'
|
|
description: |
|
|
Invoke a Supabase Function.
|
|
notes: |
|
|
- Requires an Authorization header.
|
|
- When you pass in a body to your function, we automatically attach the Content-Type header for `Blob`, `ArrayBuffer`, `File`, `FormData` and `String`. If it doesn't match any of these types we assume the payload is `json`, serialise it and attach the `Content-Type` header as `application/json`. You can override this behaviour by passing in a `Content-Type` header of your own.
|
|
examples:
|
|
- id: invoke-function
|
|
name: Basic invocation
|
|
description:
|
|
code: |
|
|
```python
|
|
resp = supabase.functions.invoke(
|
|
"hello-world",
|
|
invoke_options={
|
|
"body": { "foo": "bar" }
|
|
},
|
|
)
|
|
```
|
|
- id: error-handling
|
|
name: Error handling
|
|
description: |
|
|
Returns one of the following errors:
|
|
|
|
- `FunctionsHttpError`: if your function throws an error
|
|
- `FunctionsRelayError`: if the Supabase Relay encounters an error processing your function
|
|
isSpotlight: true
|
|
code: |
|
|
```python
|
|
from supafunc.errors import FunctionsRelayError, FunctionsHttpError
|
|
|
|
try:
|
|
resp = supabase.functions.invoke(
|
|
"hello-world",
|
|
invoke_options={
|
|
"body": {"foo": "bar"},
|
|
"headers": {"my-custom-header": "my-custom-header-value"},
|
|
},
|
|
)
|
|
except FunctionsHttpError as exception:
|
|
err = exception.to_dict()
|
|
print(f"Function returned an error {err.get("message")}")
|
|
except FunctionsRelayError as exception:
|
|
err = exception.to_dict()
|
|
print(f"Relay error: {err.get("message")}")
|
|
```
|
|
- id: passing-custom-headers
|
|
name: Passing custom headers
|
|
description: |
|
|
The library accepts custom headers via the `headers` option.
|
|
|
|
Note: `supabase-py` automatically populates the `Authorization` header if there is a signed in user.
|
|
isSpotlight: true
|
|
code: |
|
|
```python
|
|
resp = supabase.functions.invoke(
|
|
"hello-world",
|
|
invoke_options={
|
|
"headers": {
|
|
"my-custom-header": "my-custom-header-value"
|
|
},
|
|
"body": { "foo": "bar" }
|
|
}
|
|
)
|
|
```
|
|
|
|
- id: list-buckets
|
|
title: 'list_buckets()'
|
|
notes: |
|
|
- RLS policy permissions required:
|
|
- `buckets` table permissions: `select`
|
|
- `objects` table permissions: none
|
|
- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
examples:
|
|
- id: list-buckets
|
|
name: List buckets
|
|
code: |
|
|
```
|
|
res = supabase.storage.list_buckets()
|
|
```
|
|
|
|
- id: get-bucket
|
|
title: 'get_bucket()'
|
|
notes: |
|
|
- RLS policy permissions required:
|
|
- `buckets` table permissions: `select`
|
|
- `objects` table permissions: none
|
|
- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
examples:
|
|
- id: get-bucket
|
|
name: Get bucket
|
|
code: |
|
|
```
|
|
res = supabase.storage.get_bucket(name)
|
|
```
|
|
|
|
- id: create-bucket
|
|
title: 'create_bucket()'
|
|
notes: |
|
|
- RLS policy permissions required:
|
|
- `buckets` table permissions: `insert`
|
|
- `objects` table permissions: none
|
|
- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
examples:
|
|
- id: create-bucket
|
|
name: Create bucket
|
|
code: |
|
|
```
|
|
res = supabase.storage.create_bucket(name)
|
|
```
|
|
|
|
- id: empty-bucket
|
|
title: 'empty_bucket()'
|
|
notes: |
|
|
- RLS policy permissions required:
|
|
- `buckets` table permissions: `select`
|
|
- `objects` table permissions: `select` and `delete`
|
|
- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
examples:
|
|
- id: empty-bucket
|
|
name: Empty bucket
|
|
code: |
|
|
```
|
|
res = supabase.storage.empty_bucket(name)
|
|
```
|
|
- id: delete-bucket
|
|
title: 'delete_bucket()'
|
|
notes: |
|
|
- RLS policy permissions required:
|
|
- `buckets` table permissions: `select` and `delete`
|
|
- `objects` table permissions: none
|
|
- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
examples:
|
|
- id: delete-bucket
|
|
name: Delete bucket
|
|
code: |
|
|
```
|
|
res = supabase.storage.delete_bucket(name)
|
|
```
|
|
|
|
- id: from-upload
|
|
title: 'from_.upload()'
|
|
notes: |
|
|
- RLS policy permissions required:
|
|
- `buckets` table permissions: none
|
|
- `objects` table permissions: `insert`
|
|
- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
- Please specify the appropriate content [MIME type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types) if you are uploading images or audio. If no `file_options` are specified, the MIME type defaults to `text/html`.
|
|
examples:
|
|
- id: upload-file
|
|
name: Upload file using filepath
|
|
code: |
|
|
```py
|
|
with open(filepath, 'rb') as f:
|
|
supabase.storage.from_("testbucket").upload(file=f,path=path_on_supastorage, file_options={"content-type": "audio/mpeg"})
|
|
```
|
|
- id: from-move
|
|
title: 'from_.move()'
|
|
notes: |
|
|
- RLS policy permissions required:
|
|
- `buckets` table permissions: none
|
|
- `objects` table permissions: `update` and `select`
|
|
- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
examples:
|
|
- id: move-file
|
|
name: Move file
|
|
code: |
|
|
```
|
|
res = supabase.storage.from_('bucket_name').move('public/avatar1.png', 'private/avatar2.png')
|
|
```
|
|
|
|
- id: from-create-signed-url
|
|
title: 'from_.create_signed_url()'
|
|
notes: |
|
|
- RLS policy permissions required:
|
|
- `buckets` table permissions: none
|
|
- `objects` table permissions: `select`
|
|
- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
examples:
|
|
- id: create-signed-url
|
|
name: Create Signed URL
|
|
code: |
|
|
```
|
|
res = supabase.storage.from_('bucket_name').create_signed_url(filepath, expiry_duration)
|
|
```
|
|
|
|
- id: from-get-public-url
|
|
title: 'from_.get_public_url()'
|
|
notes: |
|
|
- The bucket needs to be set to public, either via [updateBucket()](/docs/reference/javascript/storage-updatebucket) or by going to Storage on [supabase.com/dashboard](https://supabase.com/dashboard), clicking the overflow menu on a bucket and choosing "Make public"
|
|
- RLS policy permissions required:
|
|
- `buckets` table permissions: none
|
|
- `objects` table permissions: none
|
|
- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
examples:
|
|
- id: get-public-url
|
|
name: Returns the URL for an asset in a public bucket
|
|
code: |
|
|
```
|
|
res = supabase.storage.from_('bucket_name').get_public_url('test/avatar1.jpg')
|
|
```
|
|
|
|
- id: from-download
|
|
title: 'from_.download()'
|
|
notes: |
|
|
- RLS policy permissions required:
|
|
- `buckets` table permissions: none
|
|
- `objects` table permissions: `select`
|
|
- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
examples:
|
|
- id: download-file
|
|
name: Download file
|
|
code: |
|
|
```
|
|
with open(destination, 'wb+') as f:
|
|
res = supabase.storage.from_('bucket_name').download(source)
|
|
f.write(res)
|
|
```
|
|
|
|
- id: from-remove
|
|
title: 'from_.remove()'
|
|
notes: |
|
|
- RLS policy permissions required:
|
|
- `buckets` table permissions: none
|
|
- `objects` table permissions: `delete` and `select`
|
|
- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
examples:
|
|
- id: delete-file
|
|
name: Delete file
|
|
code: |
|
|
```
|
|
res = supabase.storage.from_('bucket_name').remove('test.jpg')
|
|
```
|
|
- id: from-list
|
|
title: 'from_.list()'
|
|
notes: |
|
|
- RLS policy permissions required:
|
|
- `buckets` table permissions: none
|
|
- `objects` table permissions: `select`
|
|
- Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
|
|
examples:
|
|
- id: list-files
|
|
name: List files in a bucket
|
|
code: |
|
|
```
|
|
res = supabase.storage.from_('bucket_name').list()
|
|
```
|