Flutter for OpenHarmony:postgrest 直接访问 PostgreSQL 数据库的 RESTful 客户端(Supabase 核心驱动) 深度解析与鸿蒙适配指南

Flutter for OpenHarmony:postgrest 直接访问 PostgreSQL 数据库的 RESTful 客户端(Supabase 核心驱动) 深度解析与鸿蒙适配指南

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net

请添加图片描述

前言

如果你不想写复杂的 Java/Node.js 后端服务,只想直接增删改查数据库,PostgREST 是一个神奇的后端工具 —— 它能把从 PostgreSQL 数据库自动生成一套 RESTful API。而 postgrest (Dart库) 正是这一服务的官方客户端。

这也是 Supabase(Firebase 的开源替代品)的核心组件之一。通过它,你可以在 Flutter App 中像写 SQL 一样流畅地操作远程数据,既安全又高效。

一、概念介绍/原理解析

1.1 基础概念

  • Filter: eq('id', 1), gt('age', 18) 等,对应 SQL 的 WHERE
  • Select: 指定返回字段,支持关联查询(如 *, posts(*))。
  • Order: 排序规则。
  • RPC: 调用存储过程(Stored Procedures)。

HTTP 请求

SQL 语句

结果集

JSON 数据

Flutter 移动应用

PostgREST 接口网关

后台数据库

1.2 进阶概念

虽然看起来是直连数据库,但实际上通过 PostgREST 的 RLS (Row Level Security) 机制,你可以非常精细地控制每个用户只能读写自己的数据,无需担心越权。

二、核心 API/组件详解

2.1 基础用法

查询数据。

import'package:postgrest/postgrest.dart';final client =PostgrestClient('https://your-project.supabase.co/rest/v1');voidmain()async{// SELECT * FROM countries WHERE name = 'China'final data =await client .from('countries').select().eq('name','China');print(data);// List<Map<String, dynamic>>}
在这里插入图片描述

2.2 插入与更新

// INSERT INTO users (name, status) VALUES ('Tom', 'active')await client.from('users').insert({'name':'Tom','status':'active'});// UPDATE users SET status = 'inactive' WHERE id = 1await client.from('users').update({'status':'inactive'}).eq('id',1);
在这里插入图片描述

三、常见应用场景

3.1 场景 1:无后端 App

基于 Supabase 或自建 PostgREST,直接开发 CMS 或简单的社交应用。

// 获取文章列表及作者信息final posts =await client.from('posts').select('*, author:users(*)');
在这里插入图片描述

3.2 场景 2:实时排行榜

虽然 postgrest 主要是 REST,但结合 Realtime 功能(Supabase),可实现实时数据同步。

// 仅使用 postgrest 获取快照final top10 =await client.from('scores').select().order('score', ascending:false).limit(10);
在这里插入图片描述

3.3 场景 3:调用复杂业务逻辑

通过 RPC 调用数据库函数。

// 调用名为 "reset_password" 的函数await client.rpc('reset_password', params:{'email':'[email protected]'});
在这里插入图片描述

四、OpenHarmony 平台适配

4.1 网络请求库

postgrest 内部默认使用 http 库。在 OpenHarmony 上,这完全没问题。如果你需要自定义(比如加 Token 拦截器或使用 Dio),可以通过构造函数传入自定义 Client。

4.2 权限声明

同样别忘了在鸿蒙 config.json/module.json5 中声明 ohos.permission.INTERNET

五、完整示例代码

本示例列出所有任务 (Todos),并支持点击切换完成状态。

import'package:flutter/material.dart';import'package:postgrest/postgrest.dart';// 请替换为你自己的 PostgREST 服务地址constString _url ='https://my-project.supabase.co/rest/v1';constString _anonKey ='your-anon-key';// 如果有的话voidmain(){runApp(constMaterialApp(home:TodoPage()));}classTodoPageextendsStatefulWidget{constTodoPage({super.key});@overrideState<TodoPage>createState()=>_TodoPageState();}class _TodoPageState extendsState<TodoPage>{ late finalPostgrestClient _client;List<Map<String,dynamic>> _todos =[]; bool _loading =true;@overridevoidinitState(){super.initState(); _client =PostgrestClient( _url, headers:{'apikey': _anonKey},// 公钥);_fetchTodos();}Future<void>_fetchTodos()async{try{final res =await _client.from('todos').select().order('id');setState((){ _todos =List<Map<String,dynamic>>.from(res asList); _loading =false;});}catch(e){print('Error: $e');setState(()=> _loading =false);}}Future<void>_toggle(int id, bool current)async{// 乐观更新 UIfinal index = _todos.indexWhere((t)=> t['id']== id);if(index !=-1){setState((){ _todos[index]['is_complete']=!current;});}try{await _client.from('todos').update({'is_complete':!current}).eq('id', id);}catch(e){// 失败回滚..._fetchTodos();}}@overrideWidgetbuild(BuildContext context){returnScaffold( appBar:AppBar(title:constText('PostgREST Todos')), body: _loading ?constCenter(child:CircularProgressIndicator()):ListView.builder( itemCount: _todos.length, itemBuilder:(context, index){final todo = _todos[index];final isDone = todo['is_complete']as bool???false;returnCheckboxListTile( title:Text(todo['task']asString), value: isDone, onChanged:(_)=>_toggle(todo['id']as int, isDone),);},), floatingActionButton:FloatingActionButton( onPressed: _fetchTodos, child:constIcon(Icons.refresh),),);}}
在这里插入图片描述

六、总结

postgrest 极大地降低了全栈开发的门槛。前端开发者只需专注于 UI 和数据查询,复杂的后端逻辑交给强大的 PostgreSQL 数据库去处理。

最佳实践

  1. 安全性:永远不要在客户端使用 service_role 密钥(超级管理员权限)。始终使用 anon 密钥配合 RLS。
  2. 类型生成:手动解析 Map<String, dynamic> 很累且容易出错,建议使用 supabase_flutter 配合代码生成工具。

Read more

AI赋能原则1解读思考:超级能动性-AI巨变时代重建个人掌控力的关键能力

AI赋能原则1解读思考:超级能动性-AI巨变时代重建个人掌控力的关键能力

目录 一、AI 焦虑的本质:技术升级 vs. 能力结构失衡 二、什么是“超级能动性”:技术时代的人类新核心能力 三、为什么“超级能动性”能让我们重新获得掌控感? (一)认知掌控:从“我不知道如何适应 AI” → “我能塑造 AI 如何适应我” (二)任务掌控:从“我做不完” → “我调动系统来做” (三)身份掌控:从“我会不会被替代” → “我能指挥 AI 完成价值输出” 四、从技术视角看超级能动性的底层逻辑 (一)Prompt → Agent → Workflow → Multi-Agent System 的必然进化 (二)人类从“模型的用户”变成“系统的产品经理” (三)

By Ne0inhk

科研党沸腾!AutoFigure让AI一键画出Nature级别的论文插图,告别PPT地狱

前天发了一个PaperBanana文章: PaperBanana:AI科研人员画图终于不用头疼了 今天又刷到一篇ICLR 2026的论文,看完直接坐不住了。作为天天跟论文打交道的人,谁没为画一张像样的方法图熬过夜?现在终于有人把这事儿给彻底解决了——AutoFigure,一个能从长文本直接生成publication-ready科研插图的AI框架。 讲真,这次不是又来刷榜的那种工作。团队直接放了个大招:不仅搞出了第一个专门针对科研插图生成的benchmark FigureBench(3300对高质量文本-图片数据),还真的做出了一个能用的系统。最关键的是,人类专家评测显示,66.7%的生成结果达到了可以直接放进正式论文的标准。这可不是吹的,是实打实让10个一作来评价自己论文的图,然后给出的数据。 科研可视化这座大山,终于有人动了 咱们先聊聊为啥要做这个。科研插图有多重要?一张好图能让审稿人3分钟看懂你的核心思想,防止理解偏差。但问题是,画一张高质量的科研插图,往往要花好几天时间,还得同时具备专业知识和设计能力。 之前也有些相关工作,比如Paper2Fig100k、ACL-

By Ne0inhk
Z-Image LoRA 训练整合包及使用教程:使用ai-toolkit的最全面的 z-image-turbo lora训练实战教程

Z-Image LoRA 训练整合包及使用教程:使用ai-toolkit的最全面的 z-image-turbo lora训练实战教程

Z-Image LoRA 训练整合包及使用教程:使用ai-toolkit的最全面的 z-image-turbo lora训练实战教程 Z-ImageLoRA训练z-image-turbo微调教程AI绘画模型微调训练器部署数据标注 这篇文章从头到尾、手把手带你完成一套真正能用的 Z-Image LoRA(以 z-image-turbo 为基础)训练流程。文章按实操步骤拆成十部分,内容尽量贴近日常操作和命令,让你能一步步复刻。 👇️👇️教程所需的z-image lora训练整合包下载 z-image lora整合包下载地址 https://pan.quark.cn/s/c3da18507004 目录 1. 概览与准备 2. 训练集准备(图片来源与数量) 3. 标注(生成训练提示词) 4. 训练器选择与本地部署(lto-kate / l2t / toolket) 5. 上传训练集到训练器并创建数据集 6. 训练器参数设置(关键参数详解) 7. 测试提示词编写与每250步测试策略 8.

By Ne0inhk

AI的思考:从代码生成看人工智能的边界

当AI学会写代码,我们该如何重新定义“理解”? 引言 过去一年,以ChatGPT、GitHub Copilot为代表的大语言模型(LLM)席卷全球,它们不仅能聊天、写诗,还能编写代码、调试程序。许多程序员惊呼:AI要取代我们了吗?然而,当我们冷静下来审视这些生成的代码时,一个更深层的问题浮现出来:AI真的理解它写出的代码吗?它的“思考”方式与人类有何不同?本文将通过几个简单的代码生成示例,探讨AI编程背后的原理、能力边界,以及对人类程序员的启示。 一、AI写代码:一次直观的体验 让我们从一个经典的编程任务开始:写一个Python函数,计算斐波那契数列的第n项。我们将使用Hugging Face的Transformers库加载一个专门为代码生成训练的小型模型(microsoft/CodeGPT-small-py),看看它会输出什么。 python from transformers import pipeline # 加载代码生成模型(首次运行会自动下载) generator = pipeline('text-generation'

By Ne0inhk