ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

graphile-build-pg 版本演进全解析:从 5.0.0-alpha 到 5.1.3 的 API 重构、行为系统与插件生态

graphile-build-pg 版本演进全解析:从 5.0.0-alpha 到 5.1.3 的 API 重构、行为系统与插件生态 graphile-build-pg 版本演进全解析从 5.0.0-alpha 到 5.1.3 的 API 重构、行为系统与插件生态【免费下载链接】crystal Graphiles Crystal Monorepo; home to Grafast, PostGraphile, pg-introspection, pg-sql2 and much more!项目地址: https://gitcode.com/gh_mirrors/cry/crystalgraphile-build-pg是 Graphile Crystal 仓库Grafast、PostGraphile、pg-introspection、pg-sql2 等项目的集合中负责「将 PostgreSQL 数据库反射为 GraphQL schema」的核心插件集合。本文以其完整 CHANGELOG 为主体系统梳理从 5.0.0 早期 alpha 到当前 5.1.3 的版本演进脉络包括行为系统两次大重构、输入规划架构变革、source/config等命名的全面统一、schema 导出体积优化以及面向插件作者的大量 API 变化帮助你理解 PostGraphile v5 底层构建机制并据此迁移自己的插件与配置。一、模块定位graphile-build-pg 在 Graphile 技术栈中的角色在深入版本历史之前先明确这个包在生态中的位置。根据包自身 README 的说明graphile-build-pg是一组 graphile-build 插件作用是通过 pg-introspection 反射 PostgreSQL 数据库中的表、视图、函数等资源为它们构建 dataplan/pg 注册表由 codecs、resources、relations 组成再由各插件依据该注册表生成对应的 GraphQL 类型、字段与 grafast plan resolver 函数最终产出高性能、强扩展性的自动生成 GraphQL schema。它是 PostGraphile 的核心组成同时也可以脱离数据库反射、由开发者手工构建注册表来获得完全控制。从 package.json 可以看到它的关键工程属性版本5.1.3要求 Node.js22GraphQL^16.9.0依赖pg-introspection、pg-sql2、graphile-configpeer 依赖dataplan/pg、grafast、graphile-build、graphile-config、tamedevil等这些依赖关系与 CHANGELOG 中反复出现的 Updated dependencies 一一对应通过exports字段提供./dataplan/pg、./pg-introspection、./pg-sql2等转发fwd入口方便用户与插件避免重复模块问题。默认 preset 在 src/preset.ts 中定义defaultPreset由GraphileBuildPgLibPreset提供build.lib.dataplanPg、build.lib.dataplanJson、build.lib.sql三个库引用与 40 个左右插件PgBasicsPlugin、PgCodecsPlugin、PgIntrospectionPlugin、PgTablesPlugin、PgProceduresPlugin、PgRelationsPlugin、PgRBACPlugin、PgIndexBehaviorsPlugin、PgRegistryPlugin、PgPolymorphismPlugin等组成。所有插件均在 src/index.ts 中导出同时该文件通过declare global声明合并定义了GraphileBuild.PgResourceTags、PgCodecTags、PgCodecRelationTags、PgCodecRefTags、PgCodecAttributeTags以及DataplanPg各extensions的类型接口并重新导出sql/SQL对应 5.0.1 的变更。二、版本发布节奏与工程化演进CHANGELOG 记录了从5.0.0-0.12023 年 4 月前后的 initial changesets release到5.1.3的完整过程版本号形态依次为5.0.0-0.x预 alpha→5.0.0-alpha.x→5.0.0-beta.x→5.0.0-rc.x→5.0.0→5.0.1→5.0.2→5.1.0→5.1.1→5.1.2→5.1.3。其间穿插的工程化变更包括发布流程规范化5.0.0-rc.8明确「No code changes. Updates the release process, cleans up package.json, uses fixed identifiers for peer dependencies... hopefully move to trusted publishing」即转向可信发布机制包管理器兼容5.0.0-beta.46统一使用workspace:^依赖以适配 pnpm5.0.0-beta.41之后多次调整 peerDependencies 的可选标记最低运行环境提升5.0.0-beta.39将 Node 最低版本提升到 Node 22当时最新 LTS5.0.0-rc.3又重申「Node v22 is required for this module」并支持 TS 配置rewriteRelativeImportExtensions与erasableSyntaxOnly源码中使用.ts扩展名导入版本号写入源码5.0.0-alpha.14起包导出version不再用require(../package.json)hack而是由版本脚本写入 src/version.ts。三、5.1.x 稳定版新能力与边界修正5.1.0到5.1.3是 5.0.0 发布后的稳定迭代涉及大量插件作者关心的 API 与默认行为修正。3.1 新的内置类型与 codec 支持oid内置类型5.1.0PR #3084TYPES.oid被加入内置类型集合TYPES.unknowncodec5.0.2PR #3034为方便从 PostGraphile V4 迁移而新增tsvector / tsquery5.0.0-rc.6PR #2954由社区贡献者 dargmuesli 加入的全文检索类型支持这与 src/preset.ts 中独立的PgLtreePluginltree 类型5.0.0-beta.20 加入共同体现了内置 codec 类型的持续扩充JSONPath 类型5.0.0-beta.42PR #2571同样来自社区 PRbytea → Base64EncodedBinary 标量5.0.0-alpha.14二进制类型映射为 GraphQL 自定义标量嵌套数组5.0.0-alpha.12支持通过 PostgreSQL domain 构造嵌套数组类型。3.2 枚举enum相关行为收敛枚举是graphile-build-pg中最复杂的领域之一涉及 enum 类型、enum table 与 enum domain 三套机制空 enum table 的处理5.1.3PR #3121允许 PostgreSQL enum table 没有值错误延迟到 GraphQL 层捕获enum table 读取失败的降级策略5.1.0PR #3099只有当表位于已发布 schemapgServices中schemas列表内时才抛错其他 schema 中的 enum table 读取失败仅产生 warning——因为 gather 阶段无法预知 schema build 阶段是否真的会用到它enum table domains5.0.0-beta.47PR #2718从 PostGraphile V4 移植使 enum table 的值可以作为 PostgreSQL 函数的输入与输出enum 相关重构5.0.0-1.2 之前enumType工厂更名为enumCodec且只接受单个对象参数引入enumTableEnum/enumTableCodecinflection5.0.0-alpha.3修复enumsmart tag 在未指定enumName时的命名冲突5.0.0-beta.13修复 smart tags 未复制到 enum codec 的问题5.0.0-beta.11修复 enum table 引用在 Relay preset 下被错误排除的问题5.0.0-beta.29让数据库 enum 注释反映到 schema。实现层面src/plugins/PgEnumTablesPlugin.ts 展示了 enum table 的完整接入gather 阶段通过pgEnumTables帮助器isEnumConstraint、getIntrospectionData、processIntrospection、enumCodecForConstraint识别枚举约束并生成PgEnumCodeccodec 的extensions上标记isEnumTableEnum与enumTableEnumDetails从而让 GraphQL 层能将 enum table 渲染为真正的 GraphQL enum 类型。3.3 插件作者 APIbuild 快捷方式与 scope 细节build.getPgCodecByDatabaseName5.1.1PR #3105在 src/plugins/PgCodecsPlugin.ts 中被挂载到 build 上便于按数据库名serviceName schemaName name查询 codecgetGraphQLTypeByPgCodec字符串联合5.1.1PR #3108将 situationinput/output等收敛为带中央注册表的字符串联合类型IDE 可自动补全其核心实现在 src/plugins/PgBasicsPlugin.tsfieldArgs移到根计划5.1.0PR #3065fieldArgs在 root plan 中创建、在目标 step 的 layer plan 中应用修复了 fieldArgs 无法应用到带副作用 step 的问题pgResource.extensions视图标识5.1.0PR #3088新增isView、.isMaterializedView、.isForeignTable插件可据此区分资源来源build.dataplanJson5.1.0PR #3086暴露dataplan/json的副本避免插件再引入依赖build.pgResources/build.pgCodecs/build.pgRelations/build.pgExecutor快捷方式5.0.0-beta.47PR #2715映射到build.input.pgRegistry对应集合build.pgExecutor取第一个 executor多数据库场景下需改用pgExecutorspgRegistry.pgExecutors5.0.0-beta.29PR #2156executor 不再需要从 resource 反查默认名为mainscope 细化5.1.2PR #3113为 row-by-unique accessor 字段的scope增加更多细节5.0.0-beta.47PR #2706开放isPgCreateMutation/isPgUpdateMutation/isPgDeleteMutationscope 并设置 resource5.0.0-beta.18 为 ref 生成字段增加pgRefDetailsscope。3.4 索引行为与isIndexed索引推断直接决定 schema 中会出现哪些查询、过滤与排序能力因此相关修复贯穿多个版本isIndexedsmart tag5.1.1PR #3112可手动声明「列或外键约束已被索引」用于默认索引行为插件PgIndexBehaviorsPlugin的判定索引扫描范围收窄5.1.0PR #3098只有表、物化视图、外部表上的属性才被扫描索引复合类型、视图等一律「疑罪从无」这可能导致 schema 中出现更多字段视图属性索引 bug5.0.0-beta.45PR #2689修复 PgIndexBehaviorsPlugin 将视图属性全部当作未索引的问题宽松化以匹配 PG185.0.0-rc.1PR #2752放宽「列/关系可视为已索引」的条件以反映 PostgreSQL 18 的优化若想移除由此多出的字段/过滤/排序可在列上使用behavior -filterBy -orderBy在外键约束上使用behavior -select -list -connection -single -manyToMany。在 src/plugins/PgIndexBehaviorsPlugin.ts 中可以看到插件通过tbl.getIndexes()判断列是否有索引将结果写入attribute.extensions.isIndexed/relation.extensions.isIndexed并尊重tags.isIndexed的手动覆盖第 65–107、132–149 行等与 CHANGELOG 描述完全对应。3.5 其他重要行为修正Domain codec 默认值5.1.0PR #3089domain codec 可声明自身是否有默认值proc:filterBy→condition:proc:filterBy5.1.1PR #3110使 postgraphile-plugin-connection-filter 可用filter:proc:filterBy两者可独立控制导出sql与SQL5.0.1PR #2984graphile-build-pg直接再导出 pg-sql2 的sql与类型SQL见 src/index.ts主键列大小写处理5.0.0-rc.3PR #2850处理名为Id、ID、iD的主键列在id → rowId重命名时的冲突。四、5.0.0 正式版类型精确化与导出体积优化5.0.0与5.0.0-rc.8完全一致其前一个 RC 版本5.0.0-rc.6是类型与导出优化的集大成者4.1 更精确的类型更真实地反映现实extensions、extensions.tags在多数位置标记为可选PgCodecAttribute.notNull、PgResourceParameter.requires、PgCodecRelation.isUnique标记为可选pgGetArgDetailsFromParameters().argDetails.postgresArgName可能返回undefined而不只是null.required变为boolean | undefined。4.2 导出 schema 体积显著缩减以测试夹具为准减少约 20%手段包括把可选内容真正标记为可选、从配置对象中剔除多余可选字段无 tags 时不输出tags对象、内置列表类型使用LIST_TYPES、将内联函数提取为全局函数、优化 plan 函数、复用共享逻辑、简化 plan resolver、消除局部辅助函数调用中冗余的重复标识符参数等。5.0.0-beta.21还引入了EXPORTABLE的第三个参数nameHintsrc/plugins 大量使用用于提示导出变量名。4.3 内部 API 更名isExecutableStep/assertExecutableStep→isStep/assertStep5.0.0-rc.6PR #2956ExecutableStep→Step5.0.0-beta.38旧名保留但废弃ModifierStep/BaseStep被移除deepEval→applyTransforms5.0.0-alpha.15makePgResourceOptions()→pgResourceOptions()5.0.0-beta.47ObjectStepPgExecutorContextPlans...废弃改用StepPgExecutorContext...。五、beta 阶段的功能爆发期5.0.0-beta 阶段是功能增量最大的时期值得插件作者逐一对照5.1 捕获 PostgreSQL NOTICE5.0.0-beta.47PR #2716为 PostgreSQL 客户端增加捕获 SQL 查询期间RAISE NOTICE的能力CHANGELOG 给出了完整示例数据库中定义带 trigger 的表footrigger 函数tg_foo()在插入时raise notice Hello World using hint Hi, || NEW.bar然后在 schema 中通过extendSchema扩展CreateFooPayload用get($payload, result).getNotices()读取通知。响应中的messages数组包含severity、message、code、detail、hint字段例如{ severity: NOTICE, message: Hello World, code: 00000, detail: null, hint: Hi, inputvalue }。这是将数据库内部通知透传到 GraphQL 响应层的实用能力。5.2 分区表暴露控制5.0.0-beta.47PR #2725通过partitionExpose child或partitionExpose bothsmart tag 控制分区表的子分区是否暴露默认parent只暴露父分区表。全局配置项对应GraphileBuild.SchemaOptions.pgDefaultPartitionedTableExpose见 src/index.ts可选值parent/child/both。5.3 多态polymorphism体系完善returnType MyTypesmart tag5.0.0-beta.18指定函数返回的多态子类型interface mode:union的根字段5.0.0-alpha.8、interface modesingle/relational在有主键时获得Node接口、modeunion不再自动获得Node需behavior node5.0.0-beta.4pgUnionAll()支持only参数限制结果类型5.0.0-beta.16对应PgPolymorphismOnlyArgumentPlugin修复mode:union-returning函数产生非功能字段5.0.0-beta.43、关系型多态的约束查找5.0.0-alpha.14等。5.4 Node ID 体系演进nodeIdCodecsmart tag 与preset.schema.defaultNodeIdCodec全局设置5.0.0-beta.44默认base64JSONcodec 被烘入 NodeId handler5.0.0-alpha.15node(codecs, handler, $id)简化为node(handler, $id)NodeIdHandler新增运行时方法getIdentifiers5.0.0-beta.38 前后解码 Node ID 时使用inhibitOnNull防止用错误类型的 ID 取数据5.0.0-beta.21Relay preset 下用不兼容的 Node ID 过滤不再产生怪异结果5.0.0-beta.21。5.5 计算列与函数计算列输入在 root layer plan 中规划5.0.0-beta.39PR #2525提升 plan 去重与 SQL 生成效率同时修复 Relay preset 下可空 nodeID 参数导致整个 select 被抑制的 bug突变后的计算列快照问题5.0.0-beta.45PR #2686由于 Postgres 机制突变后计算列会使用突变前快照修复方式是把 post-mutation 函数调用拆分为独立语句pgOrderByNullsLast应用于计算列5.0.0-rc.1PR #2758其实现见 src/plugins/PgOrderAllAttributesPlugin.ts 与 src/plugins/PgOrderByPrimaryKeyPlugin.ts函数参数 required → optional5.0.0-rc.7PR #2968parameter.required被反义属性parameter.optional取代省略配置默认视为「必需」与 Postgres 默认一致提供了临时 getter 兼容但导出可执行 schema 时不会保留V5 发布后会移除兼容垫片arg0variant nodeId5.0.0-alpha.13让函数第一个参数数字 0 可递增接受 Node ID当前仅支持表类型参数稳定 void 函数5.0.0-0.15与 out 参数/returns table的参数必需性识别修复5.0.0-beta.32影响pgStrictFunctions用户。5.6 Relay preset 与连接功能postgraphile/presets/relay5.0.0-alpha.13隐藏主键/外键列改用id: ID、隐藏参与主键/外键的 CRUD 与过滤列、禁止按单个主键/外键列排序、关闭非 Node ID 的 row fetcher 与 CRUD mutation、函数参数支持arg0variant nodeId、从 mutation payload 移除冗余关系多数变化可逆如给 unique 约束加connectionbehavior 可恢复userByUsernameconnection() step 配置对象化5.0.0-beta.21connection($list, nodePlan, cursorPlan)变为connection($list, { nodePlan, cursorPlan })并支持edgeDataPlan关联 edge 数据ConnectionStep/EdgeStep获得get()方法使*Connection.edges/nodes/pageInfo与*Edge.node/cursor无需再定义 planpgUnionAll 连接修复5.0.0-alpha.8startCursor/endCursor与 PageInfoAmber preset 关闭反向分页默认值5.0.0-beta.29函数默认不再启用before/last需backwardsbehavior 恢复V4 preset 不受影响cursor 分页支持可空列5.0.0-alpha.12should now work, although it is untested按 CHANGELOG 原文如实引用。六、行为系统behavior system的两次大重构行为系统是本包最核心也最常被插件作者修改的机制CHANGELOG 记录了它从「schema 构建期的即席判断」到「集中注册表」的演进6.1 第一次重构5.0.0-alpha.11旧机制下每个插件在自己的 hook 里各自计算默认行为并调用getBehavior([...extensions 列表])导致同样的实体在不同插件眼中行为可能不同也难以回答「该实体最终行为是什么」。新机制为每个实体一次性确立行为插件通过plugin.schema.entityBehaviors注册代码从const defaultBehavior someCondition(relation) ? behavior_if_true : behavior_if_false; const behavior getBehavior([relation.remoteResource.codec.extensions, relation.remoteResource.extensions, relation.extensions]); if (build.behavior.matches(behavior, behavior_to_test, defaultBehavior)) { doTheThing(); }简化为if (build.behavior.pgCodecRelationMatches(relation, behavior_to_test)) { doTheThing(); }6.2 第二次重构5.0.0-beta.29行为系统进一步引入「已知行为的集中注册表」更细致地应用行为、移除大量 hackdefaultBehavior: -*现在可以正确工作addBehaviorToTags()被移除改用plugin.schema.entityBehaviors。由于行为应用顺序改变可能出现「不同行为最终胜出」的情况例如给一个没有执行权限的函数加filterable现在会出现在 schema 中用户 smart tag 覆盖推断行为此前则不会。CHANGELOG 明确建议升级前后打印 schema 对比并提示可用graphile behavior debugCLI 排查同时行为字符串的写法建议从字符串改为数组以获得自动补全defaultBehavior: connection -list as GraphileBuild.BehaviorString // 或 defaultBehavior: [connection, -list]6.3 行为字符串的持续演进(query|singularRelation|manyRelation|queryField|typeField):(list|connection|single)→$1:source:$25.0.0-0.17*:source:*→*:resource:*5.0.0-1.1 的大改名见下节更细粒度的 codec 行为array:attribute:filterBy等曾被引入又回退5.0.0-alpha.15改为通过entityBehaviors按属性类型动态增删基础行为内置 codec 的「自然排序/自然相等」概念5.0.0-beta.42无自然排序的 codec 默认禁用排序无自然相等的默认禁用过滤Amber preset 的 order/filter 选项因此减少V4 preset 用户不受影响pgCodecRef行为回调参数改为[codec, refName]元组5.0.0-beta.28pgCodecAttribute行为回调使用attributeName而非 attribute 对象5.0.0-alpha.13。七、输入规划input planning架构变革5.0.0-beta.38PR #2376对输入规划做了根本性重构输入应在运行时求值移除更多 plan-time step 求值。主要变化包括FieldArgs.get移除改用FieldArgs.getRaw或bakedInput()FieldArgs新增.typeAt(path)输入对象字段不再有applyPlan/inputPlan取而代之的是运行时apply()与baked()autoApplyAfterParentPlan、autoApplyAfterParentApplyPlan、autoApplyAfterParentInputPlan、autoApplyAfterParentSubscribePlan等全部废弃beta.38 会直接对 schema 中出现这些属性抛错一批*Step改名为*并在运行时执行ModifierStep→Modifier、PgConditionStep→PgCondition、PgBooleanFilterStep→PgBooleanFilter、PgTempTableStep→PgTempTable等PgSelectStep/PgUnionAllStep引入运行时 query builder 与apply()PgInsertSingle/PgUpdateSingle/PgDeleteSingle也获得 query builderquery builder 新增meta元数据对象现用于实现clientMutationIdplaceholder从运行时相关的 modifier 中移除改用sqlValueWithCodec(value, codec)wherePlan/havingPlan移除改用fieldArg.apply($unionAll, qb qb.whereBuilder())PostgreSQL 参数分析从 plan-time 移到 runtimePR #2384并提供makeArgsRuntime帮助器PR #2407供 postgraphile-plugin-connection-filter 使用参数分析缓存PR #2407允许调用方传入 plan-time 生成的参数分析结果避免运行时重复计算。早在此前5.0.0-alpha.11 已经移除了 fieldArgs 的「隐式应用」机制不再自动为未访问的 fieldArgs 调用applyPlan插件需显式声明autoApplyAfterParent{Plan,SubscribePlan,InputPlan,ApplyPlan}: true。八、命名与 API 统一从「source/config」到「resource/service」5.0.0-1.1PR #271进行了大规模改名RENAME ALL THE THINGS并贯穿后续多个版本pgConfigs→pgServicesmakePgConfig→makePgService并由此演进到 5.0.0-0.18 的makePgConfig单数形式与对象参数{connectionString, schemas, superuserConnectionString}再到 5.0.0-beta.26 的 adaptor 直接传实例adaptor: await import(dataplan/pg/adaptors/pg)PgSource→PgResourcePgTypeCodec→PgCodecPgEnumTypeCodec→PgEnumCodecPgTypeColumn→PgCodecAttributesource→resourcePgSourceBuilder由PgResourceOptions与makeRegistryBuilder/makeRegistry取代build.input.pgSources改为build.input.pgRegistry.pgResources新增PgRegistryPlugin关系从「resource 到 resource」变为「codec 到 resource」关系 inflectionsingleRelation、manyRelationConnection等参数改为{registry, codec, relationName}databaseName→serviceNamePgDatabaseConfiguration→PgServiceConfigurationPgResourceConfig.source→fromhelpers.pgIntrospection.getDatabase→getService等recordType→recordCodeclistOfType→listOfCodec5.0.0-1.2PgV4NoIgnoreIndexesPlugin→PgIndexBehaviorsPlugin并移入本包且默认启用5.0.0-1.1config.schema.orderByNullsLast→config.schema.pgOrderByNullsLastPgInsertStep/pgInsert()等 →PgInsertSingleStep/pgInsertSingle()为未来 bulk API 留出命名空间PgConnectionArgFirstLastBeforeAfterPlugin→PgFirstLastBeforeAfterArgsPluginPgRBACPlugin纳入默认 preset5.0.0-0.32pgConfig.listen移除、改由 PgSubscriber 承担同版本make...Plugin前后缀从插件工厂移除5.0.0-beta.42旧名仍兼容。九、对插件作者与用户的迁移建议综合 CHANGELOG 中所有标注 的破坏性变更迁移要点可归纳为先 diff schema 再升级行为系统两次重构、inflection 修正5.0.0-beta.33 引入 raw backing inflectors 并把id→rowId迁移到_attributeName都可能改变最终 schemaCHANGELOG 反复强调升级前后用lexicographicSortSchema对比行为写法改用数组defaultBehavior: [connection, -list]以享受自动补全有需要时用graphile behavior debug调试输入规划 API 全部更新删除inputPlan/applyPlan/autoApplyAfterParent*改用运行时apply()/baked()、bakedInput()、fieldArg.apply()重命名清单逐项替换pgConfigs→pgServices、PgSource→PgResource、PgTypeCodec→PgCodec、required→!optional、resolveVia()返回结构变为{relationName, attributeName, relation, attribute}5.0.0-beta.42等refs 命名不再自动单复数化5.0.0-beta.45refSingle/refList/refConnection直接按原标识符 后缀处理需要旧行为可参考 CHANGELOG 提供的MyRefsInflectionPlugin覆写示例关注默认行为变化Amber preset 默认忽略 unlogged 表5.0.0-beta.29、函数默认关闭反向分页、volatile 函数的notNull语义变为作用于 payload 字段而非 mutation 字段等foreignFieldName语义变化5.0.0-0.14现在会进入inflection.connectionField(...)/listField(...)foreignSimpleFieldName可能不再需要各*FieldNamesmart tag 不再经过camelCase5.0.0-0.15。十、如何验证与深入源码单元测试本包测试位于 graphile-build/graphile-build-pg/tests如utils.test.ts覆盖parseDatabaseIdentifier等工具运行yarn testjest即可源码入口插件集合与类型声明见 src/index.ts默认 preset 组合见 src/preset.ts全部 40 个插件位于 src/plugins示例与运行仓库 src/examples 提供schema-export.ts、NO_DATA_GATHERING.ts手工构建注册表、fastify-helix-envelop.ts等服务端集成示例webpack.ts/webpack-entry-file.ts展示打包场景版本信息当前版本5.1.3与依赖范围见 package.json运行时要求 Node 22 与 GraphQL 16.9enum thunk 支持是硬性要求5.0.0-beta.47 明确「enums will now break without this」。通过以上梳理可以看出graphile-build-pg的版本历史本质上是 PostGraphile v5 从零到稳定的一次大规模 API 重塑行为系统从分散走向集中输入规划从 plan-time 走向 runtime命名从含糊走向精确schema 导出不断瘦身。对于插件作者而言这份 CHANGELOG 既是迁移手册也是理解 Grafast 数据规划模型如何与 PostgreSQL 反射结合的最佳入门材料。【免费下载链接】crystal Graphiles Crystal Monorepo; home to Grafast, PostGraphile, pg-introspection, pg-sql2 and much more!项目地址: https://gitcode.com/gh_mirrors/cry/crystal创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表