惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

人人都是产品经理
人人都是产品经理
博客园_首页
IT之家
IT之家
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Vercel News
Vercel News
美团技术团队
D
Docker
WordPress大学
WordPress大学
T
Tailwind CSS Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
The Cloudflare Blog
Y
Y Combinator Blog
F
Fortinet All Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
G
Google Developers Blog
爱范儿
爱范儿
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
月光博客
月光博客
MongoDB | Blog
MongoDB | Blog
S
SegmentFault 最新的问题
GbyAI
GbyAI
Hugging Face - Blog
Hugging Face - Blog
Microsoft Azure Blog
Microsoft Azure Blog
A
About on SuperTechFans

Supabase Blog

AI Agents Know About Supabase. They Don't Always Use It Right. Custom OIDC Providers for Supabase Auth 100,000 GitHub stars Supabase docs over SSH Navigating Regional Network Blocks Supabase Joins the Stripe Projects Developer Preview Log Drains: Now available on Pro Supabase Storage: major performance, security, and reliability updates Supabase incident on February 12, 2026 Hydra joins Supabase X / Twitter OAuth 2.0 is now available for Supabase Auth BKND joins Supabase Supabase is now an official Claude connector Supabase PrivateLink is now available Introducing: Postgres Best Practices When to use Read Replicas vs. bigger compute Introducing TRAE SOLO integration with Supabase Supabase Security Retro: 2025 Sync Stripe Data to Your Supabase Database in One Click Building ChatGPT Apps with Supabase Edge Functions and mcp-use Own Your Observability: Supabase Metrics API Introducing iceberg-js: A JavaScript Client for Apache Iceberg Introducing Supabase for Platforms Adding Async Streaming to Postgres Foreign Data Wrappers Build "Sign in with Your App" using Supabase Auth Introducing Seven New Email Templates for Supabase Auth The new Supabase power for Kiro Introducing Supabase ETL Introducing Analytics Buckets Introducing Vector Buckets
dbdev: PostgreSQL Package Manager
Oliver Rice, John Dalton · 2023-04-14 · via Supabase Blog

dbdev: PostgreSQL Package Manager

Today we’re publicly previewing database.dev, a PostgreSQL package manager. At this stage the package registry is read-only. We've preloaded it with a handful of packages to showcase some of the more interesting possibilities.

dbdev fills the same role for PostgreSQL as npm for JavaScript, pip for Python and cargo for Rust in that it enables publishing libraries and applications for repeatable deployment. We'll be releasing the tooling necessary for third-parties to publish packages to the registry once we’ve collected some community feedback and incorporate any great new ideas. Our goal is to create an open ecosystem for packaging and discovering SQL.

The initial preview is compatible with new projects on the Supabase platform. It can also be installed on any PostgreSQL instance that support pg_tle and pgsql-http.

The in-database client is the easiest way to get started. You can setup the installer by executing the SQL snippet available at database.dev/installer.

Once the dbdev client is present, packages can be installed from the registry as shown below:


_10

-- Load the package from the package index

_10

select

_10

dbdev.install ('olirice-asciiplot');

_10

_10

-- Enable the extension

_10

create extension "olirice-asciiplot" version '0.2.1';


You can explore all available packages on database.dev.

Notice that PostgreSQL sees the olirice-asciiplot package as a native extension, rather than a raw snippet of SQL. That approach allows us to leverage PostgreSQL's builtin tooling for extension management.

With our extension installed, you can use it like any other PostgreSQL extension. Continuing with the olirice-asciiplot example, we can call the scatter function it provides to create an ASCII scatterplot:


_28

select

_28

scatter(

_28

val::numeric, -- x

_28

val::numeric, -- y

_28

'stonks!', -- title

_28

15, -- height

_28

50 -- width

_28

)

_28

from

_28

generate_series(1,10) z(val);

_28

/*

_28

stonks!

_28

----------------------------------------------

_28

| *

_28

|

_28

| *

_28

| *

_28

|

_28

| *

_28

|

_28

| *

_28

| *

_28

|

_28

| *

_28

|

_28

| *

_28

| *

_28

*/


PostgreSQL's extension tooling is excellent, but it predates some practices learned from best-in-class package indexes like crates.io. To give developers a more modern development experience, we opted to layer additional strictness on top of what PostgreSQL imposes:

Versioning#

The extension system has full support for versioning and migrations. Officially, PostgreSQL has loose constraints for version names. We made the choice to enforce a lite version of Semantic Versioning that restricts version numbers to major.minor.patch so authors can communicate bug-fixes, features, and breaking changes in a familiar way.

Namespaces#

Two common challenges faced by package indexes are name squatting and typo squatting.

  • Name squatting: reserving names for future use
  • Typo squatting: reserving misspelling of existing package

The ethics of name squatting get dicey at scale while typo squatting is widely viewed as malicious behavior. To mitigate both issues, all packages published to database.dev are namespaced to their owning organization or user’s handle. For example a package named olirice-index_advisor was created by the account olirice under the name index_advisor. If another user, some_user, forks and republishes the project, it would be available under some_user-index_advisor. Problem solved ✅

database.dev is not coupled to the Supabase platform. dbdev can load SQL libraries on any PostgreSQL instance with the required base extensions. However, using dbdev in tandem with Supabase yields some extra possibilities.

Supabase reflects APIs directly from your database’s structure, so a package can contain an entire stateful application, pre-configured with authentication, REST, GraphQL, and realtime change data capture all baked in!

For example, our friends at LangChain published a Supabase backend for their docs search tool that uses a hybrid of document embeddings and full text search to find relevant documents for a user’s query

Its available at langchain-hybrid_search and here’s how you’d set it up:


_10

select

_10

dbdev.install ('langchain-hybrid_search');

_10

_10

create extension if not exists vector;

_10

_10

create extension "langchain-hybrid_search" schema public version '1.0.0';


That creates the relevant documents table and associated search functions. Then, you can immediately hit it from your front end for best-in-class document search.


_29

import { OpenAIEmbeddings } from 'langchain/embeddings/openai'

_29

import { createClient } from '@supabase/supabase-js'

_29

import { SupabaseHybridSearch } from 'langchain/retrievers/supabase'

_29

_29

const privateKey = process.env.SUPABASE_PRIVATE_KEY

_29

if (!privateKey) throw new Error(`Expected env var SUPABASE_PRIVATE_KEY`)

_29

_29

const url = process.env.SUPABASE_URL

_29

if (!url) throw new Error(`Expected env var SUPABASE_URL`)

_29

_29

export const run = async () => {

_29

const client = createClient(url, privateKey)

_29

_29

const embeddings = new OpenAIEmbeddings()

_29

_29

const retriever = new SupabaseHybridSearch(embeddings, {

_29

client,

_29

// Below are the defaults, expecting that you set up your supabase table and functions according to the guide above. Please change if necessary.

_29

similarityK: 2,

_29

keywordK: 2,

_29

tableName: 'documents',

_29

similarityQueryName: 'match_documents',

_29

keywordQueryName: 'kw_match_documents',

_29

})

_29

_29

const results = await retriever.getRelevantDocuments('hello bye')

_29

_29

console.log(results)

_29

}


That's it for the dbdev announcement, but a package index is less interesting than what you can do with it! In that vein, the following highlights a few of packages I thought were interesting enough to callout:

burggraf-pg_headerkit is a toolkit for adding advanced features to PostgREST APIs (including Supabase REST):

  • rate limiting
  • IP allowlisting/denylisting
  • request logging

and more.

For example, you could apply a deny listing to your API using hdr.in_deny_list() in a row level security policy or view:


_10

select

_10

*

_10

from app.memos

_10

where not hdr.in_deny_list();


olirice-index_advisor#

olirice-index_advisor is one of the projects we cut from Launch Week 7. It is simple tool that takes a query and recommends indexes to minimize the “total_cost” according to the query’s explain plan.

We ultimately ran out of time to squeeze the feature in, but the optimizer works just fine:


_15

select dbdev.install('olirice-index_advisor');

_15

create extension if not exists hypopg;

_15

create extension "olirice-index_advisor";

_15

_15

-- Create a dummy table

_15

create table account(

_15

id int primary key,

_15

name text

_15

);

_15

_15

-- Search for indexes to optimize "select id from account where name = 'adsf'"

_15

select

_15

*

_15

from

_15

index_advisor($$select id from account where name = 'Foo'$$)


which shows


_10

| startup_cost_before | startup_cost_after | total_cost_before | total_cost_after | index_statements |

_10

| ------------------- | ------------------ | ----------------- | ---------------- | ----------------------------------------------------- |

_10

| 0.00 | 1.17 | 25.88 | 6.40 | {"CREATE INDEX ON public.account USING btree (name)"} |


In other words, it recommends the index CREATE INDEX ON public.account USING btree (name) which is expected to reduce the total cost from 25.88 to 6.40 for a 4x decrease.

olirice-index_advisor is compatible with tables, views, and materialized views. It can also see through views to find relevant indexes on underlying tables, and supports generic query arguments. For example, $1 in select id from account where name = $1, which makes it compatible with queries from pg_stat_statements and queries generated by the REST API.

Keep an eye open for it in Launch Week 8.

michelp-adminpack#

michelp-adminpack is a collection of tools helpful for administrating your database that we often use internally at Supabase. It holds views for reviewing useful info for debugging and optimizing performance like duplicate indexes, index usage, and table size, to name a few.

For example, to identify potentially unused indexes that can be dropped, you could use the index_usage view, which has columns for:

ColumnType
schemanamename
tablenamename
num_rowsbigint
table_sizetext
index_namename
index_sizetext
uniquetext
number_of_scansbigint
tuples_readbigint
tuples_fetchedbigint

There are several procedural languages (PL) that can be embedded in PostgreSQL and used to define functions. The ones that ship with stock PostgreSQL are SQL, and pl/pgSQL but there others that can be installed separately, including pl/v8 for JavaScript, or pl/perl for Perl. A trusted language has been restricted to remove potentially hazardous functionality like access to the network stack and file system. pl/v8 and pl/perl are examples of trusted languages. In contrast, pl/python3u is untrusted.

A Trusted Language Extension (TLE) is a PostgreSQL extension, written exclusively using trusted languages. In some ways that makes them less flexible than classic extensions, which can have C language components (more on that in a second). The advantage to TLEs is that they don't require direct access to the PostgreSQL server’s file system to install. That enables TLEs to be installed by end-users rather than by database administrators or hosting providers. TLEs are the enabling technology that allows a package manager like dbdev to function on hosted PostgreSQL platforms like Supabase.

For a more in-depth explanation of Trusted Language Extensions checkout AWS's pg_tle on Supabase blog post or dive into the code at github.com/aws/pg_tle.

A recent development in the PostgreSQL extension ecosystem is the 1.0 release of a new trusted language, pl/rust, allowing users to define SQL functions written in Rust. As a compiled language, pl/rust functions can execute an order of magnitude faster than pl/pgSQL for computationally heavy workloads. That closes the biggest capability gap between native extensions with C components and TLEs. pl/rust hasn’t released to Supabase yet, but we’re excited about rolling it out in the coming weeks.

As this is a preview, we anticipate that there may be a few rough edges. If you do take the time to explore dbdev at this stage, please contribute to its development at github.com/supabase/dbdev.

We are particularly interested in hearing about:

  1. Any issues or bugs you encounter
  2. Feature requests and suggestions for improvement
  3. Contributions in the form of code, documentation, or testing