使用JSON文件为Supabase PostgreSQL数据库加载种子数据失败及同步种子与测试数据的方案咨询
使用JSON文件为Supabase PostgreSQL数据库加载种子数据失败及同步种子与测试数据的方案咨询
一、为什么pg_read_file('./notifications.json')会报错?
你遇到的问题核心在于PostgreSQL的pg_read_file()函数是在数据库服务器的文件系统中查找文件,而不是你的本地项目目录。
当你运行supabase db reset或者supabase db push --include-all时,Supabase的本地引擎(或远程PostgreSQL服务器)并不会自动把你项目里的notifications.json文件复制到PostgreSQL有权限访问的路径下。所以函数执行时自然会提示“文件不存在”,哪怕你在本地项目里能看到这个文件。
二、正确加载本地JSON文件作为种子数据的方案
这里给你两个实用的替代方案,都能绕过pg_read_file的路径限制:
方案1:利用psql的变量注入读取本地JSON
Supabase CLI底层用psql执行SQL脚本,你可以用psql的\set命令结合shell命令读取JSON文件内容,再注入到SQL中,效果和你之前内嵌JSON的版本一致:
-- 在seed.sql中使用以下代码 \set notifications_json `cat ./notifications.json` WITH notification_json (doc) AS ( VALUES (:'notifications_json'::json) ) INSERT INTO authenticated_access.notifications_by_user (sender, receiver, type_of_notification, read_by_receiver) SELECT n.sender, n.receiver, n.type_of_notification, n.read_by_receiver FROM notification_json l CROSS JOIN LATERAL JSON_POPULATE_RECORDSET(NULL::authenticated_access.notifications_by_user, doc) AS n;
注意:如果你的JSON文件里包含单引号,需要先转义,否则会触发SQL语法错误。可以用sed命令帮你转义:
\set notifications_json `sed "s/'/''/g" ./notifications.json`
方案2:用脚本语言(Node.js/Python)编写种子逻辑
如果你的种子数据需要预处理(比如生成动态ID、过滤数据),或者JSON结构复杂,用脚本语言会更灵活:
- 写一个比如
seed.js的脚本,读取notifications.json文件; - 用Supabase客户端库(如
@supabase/supabase-js)直接连接数据库,批量插入数据; - 在
supabase/config.toml中配置种子脚本路径:[db] seed_script = "./seed.js"
这样运行supabase db reset时,CLI会自动执行这个脚本,完成数据插入。
三、同步种子数据与E2E测试数据的更好实践
要实现“单一数据源同步种子和测试”,可以参考这些实践:
- 统一数据源路径:把JSON文件放在项目的共享目录(比如
./data/shared/notifications.json),种子脚本和E2E测试都从这个路径读取数据; - 测试前初始化数据库:在E2E测试的前置钩子(比如Playwright的
test.beforeEach、Cypress的before)中,读取JSON文件,通过Supabase API或直接SQL插入来重置数据库状态,确保测试环境和种子数据完全一致; - 种子脚本可重复执行:在插入数据前先清空目标表(或者用
ON CONFLICT跳过已存在的数据),避免supabase db push或重复执行种子脚本时出现主键冲突等错误:-- 插入前清空表(适合开发环境) TRUNCATE TABLE authenticated_access.notifications_by_user CASCADE; -- 或者用ON CONFLICT跳过(适合需要保留部分数据的场景) INSERT INTO ... ON CONFLICT (id) DO NOTHING;
备注:内容来源于stack exchange,提问作者tobias hassebrock
相关产品推荐
相关产品推荐

