- 后端
【免费下载链接】keystone
The superpowered headless CMS for Node.js — built with GraphQL and React
本指南以 Keystone 官方博客《Keystone now supports MySQL》为骨架展开,结合当前仓库中的源码、配置文档与测试代码,系统讲解 MySQL 作为数据库供应商的配置方式、与 Postgres/SQLite 的关键差异、id 字段选择以及测试工具用法。读完本文,你将能够为 Keystone 项目一键切换 MySQL,并规避跨数据库行为差异带来的坑。
引言:Keystone 的三大数据库供应商
Keystone 是一个基于 Node.js、以 GraphQL 与 React 构建的超强 headless CMS(无头内容管理系统)。Keystone 官方博客于 2022 年 6 月宣布:Keystone 正式支持 MySQL,至此支持的数据库类型达到三种——PostgreSQL、MySQL 与 SQLite。
从源码角度看,这三种数据库类型的支持在 packages/core/src/types/core.ts 中被定义为一个联合类型:
export type DatabaseProvider = 'sqlite' | 'postgresql' | 'mysql'而在配置校验层(packages/core/src/schema.ts),Keystone 会对db.provider做白名单校验,只接受这三个值:
if (!['postgresql', 'sqlite', 'mysql'].includes(config.db.provider)) { throw new TypeError(`"db.provider" only supports "sqlite", "postgresql" or "mysql"`) }在生成 Prisma schema 时,packages/core/src/lib/core/prisma-schema-printer.ts 会直接将db.provider原样写入datasource块:
datasource mysql { provider = "mysql" }也就是说,Keystone 的数据库能力由对应的 Prisma provider(postgresql、mysql、sqlite)驱动,开发者只需在db配置中声明 provider,即可获得整套 schema 生成、迁移与 GraphQL 查询能力。
MySQL 数据库配置:最简起步
官方博客给出的 MySQLdb.config示例(db.provider为'mysql',连接串指向本地 3306 端口的keystone数据库,并使用uuid作为 id 字段)如下:
export default config({ db: { provider: 'mysql', url: 'mysql://dbuser:dbpass@localhost:3306/keystone', idField: { kind: 'uuid' }, }, ... });这是最直观的起步写法:provider声明数据库类型,url给出包含用户名、密码、主机、端口与库名的标准 MySQL 连接串。idField: { kind: 'uuid' }指定列表主键使用 UUID 字符串,而非默认的自增整数。
基于驱动适配器的现代配置(推荐)
随着 Prisma 驱动适配器(driver adapter)机制的引入,当前仓库的官方配置文档(docs/content/docs/config/config.md)推荐在db中使用prismaClientOptions显式传入适配器。MySQL 对应的适配器是@prisma/adapter-mariadb(MariaDB 协议与 MySQL 兼容,可直连 MySQL 服务器):
import { PrismaMariaDb } from '@prisma/adapter-mariadb' export default config<TypeInfo>({ db: { provider: 'mysql', prismaClientOptions: () => ({ adapter: new PrismaMariaDb(process.env.DATABASE_URL!), }), onConnect: async context => { /* ... */ }, idField: { kind: 'uuid' }, }, /* ... */ })配置项说明:
provider:取值固定为'mysql',由 DatabaseProvider 约束;prismaClientOptions:返回 Prisma Client 构造选项的函数,其中必须包含adapter;onConnect:接收 KeystoneContext(如数据播种等启动期动作);idField:id 字段种类,可为cuid(默认)、uuid、nanoid、ulid或autoincrement;MySQL 与 PostgreSQL 上autoincrement还可指定type: 'BigInt'。
配套地,还需要在prisma.config.ts中为 Prisma CLI 提供数据源 URL(keystone dev内部的prisma db push依赖它):
import 'dotenv/config' import { defineConfig, env } from 'prisma/config' export default defineConfig({ schema: 'schema.prisma', migrations: { path: 'migrations' }, datasource: { url: env('DATABASE_URL'), // only necessary if you want to use a specific shadow database shadowDatabaseUrl: env('SHADOW_DATABASE_URL'), }, })注意,prismaClientOptions(运行时的 Prisma Client)与prisma.config.ts(Prisma CLI)是两套独立的配置来源,不要混用。
三种数据库的关键差异与选型依据
官方博客明确指出“Postgres 与 MySQL 在运行方式上存在差异”,并引导读者参考《choosing the right database》指南。仓库中的 docs/content/docs/guides/choosing-a-database.md 给出了选型时最需要关注的三个差异点:
1. 大小写敏感性(Case Sensitivity)
- Postgres默认区分大小写;使用
StringFilter时可用mode: insensitive实现不区分大小写的查询; - MySQL默认不区分大小写;
- SQLite对
contains、startsWith、endsWith不区分大小写; - 注意:
mode: insensitive在 MySQL 与 SQLite 上不被支持。
这意味着同样的 GraphQL 过滤与排序查询,在不同数据库上的结果可能不同,取决于数据库的 collation(排序规则)。
2. 字段默认类型差异
Prisma 针对不同数据库使用不同的默认列类型。例如 Keystone 的text字段在 Prisma 中映射为String:
- Postgres:使用
text列类型; - MySQL:使用
varchar(191)列类型。
如需覆盖默认类型,Keystone 的text字段支持db.nativeType选项。从源码 packages/core/src/lib/core/prisma-schema-printer.ts 可以看到,nativeType 会以@${datasourceName}.${nativeType}的形式打印进生成的 schema,例如@mysql.VarChar(255)。
3. 自增整数字段的要求
当 Integer 字段使用defaultValue: { kind: 'autoincrement' }时,MySQL 要求该字段必须带索引,即同时设置isIndexed: true或isIndexed: 'unique'。Postgres 没有这个限制。
从源码(packages/core/src/fields/types/integer/index.ts、packages/core/src/fields/types/bigInt/index.ts)看,autoincrement还受若干约束校验:例如 SQLite 不支持BigInt类型的自增 id(packages/core/src/lib/id-field.ts),因此跨数据库迁移时要特别注意。
id 字段:从autoincrement到uuid
官方博客示例特意为 MySQL 选择了idField: { kind: 'uuid' },这与 MySQL 自增主键的行为差异直接相关。Keystone 支持五种 id 种类,具体映射逻辑位于 packages/core/src/lib/id-field.ts:
| idField kind | Prisma 标量 | 默认值 |
|---|---|---|
cuid(默认) | String | cuid 生成器 |
uuid | String | uuid 生成器 |
nanoid | String | nanoid 生成器(可配length) |
ulid | String | ulid 生成器 |
autoincrement | Int(或type: 'BigInt') | 数据库自增 |
当kind为autoincrement时,可选的type在 MySQL/PostgreSQL 上支持BigInt;而 SQLite 不支持 BigInt 自增 id,会在校验阶段直接抛错。因此:
- 若希望主键为随机字符串(便于分布式生成、避免暴露数据量),使用
uuid/cuid/nanoid/ulid; - 若希望沿用数据库自增主键,使用
autoincrement,并注意 MySQL 下列字段的索引要求(见上文)。
MySQL 下的测试:@keystone-6/core/testing/mysql
仓库为 MySQL 提供了专门的测试工具,入口为 packages/core/src/testing/mysql.ts。它封装了 MySQL/MariaDB 连接的常用流程:
resetDatabase(config, migrationsDirectory):解析连接串中的数据库名,先尝试连接目标库;若库不存在(ER_BAD_DB_ERROR/ errno 1049),会先自动创建;- 通过
mysql系统库建库,使用CREATE DATABASE ... CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci(errno 1007 表示库已存在,忽略); - 随后 DROP 并重建目标库,再依次执行
migrationsDirectory下的迁移 SQL,完成测试库重置。
升级指南(docs/content/docs/guides/migrate-to-8.md)指出,测试工具按 provider 拆分:PostgreSQL 使用@keystone-6/core/testing/postgresql,MySQL 使用@keystone-6/core/testing/mysql。API 测试套件(tests/api-tests/utils.ts)也展示了按DATABASE_URL前缀自动选择 provider 并构造对应适配器的标准做法:
if (dbUrl.startsWith('mysql:')) return 'mysql' as const // ... return { adapter: new PrismaMariaDb(url) }这与你生产环境配置中的prismaClientOptions使用方式完全一致。
完整实战示例:将现有项目切换到 MySQL
综合上述内容,一个可落地的 MySQL 配置如下(可直接复制到keystone.ts):
import { config } from '@keystone-6/core' import { PrismaMariaDb } from '@prisma/adapter-mariadb' export default config({ db: { provider: 'mysql', url: process.env.DATABASE_URL!, prismaClientOptions: () => ({ adapter: new PrismaMariaDb(process.env.DATABASE_URL!), }), onConnect: async context => { // 可选:启动时执行数据播种等操作 }, idField: { kind: 'uuid' }, }, lists: { /* ... */ }, })环境变量示例(DATABASE_URL):
DATABASE_URL="mysql://dbuser:dbpass@localhost:3306/keystone"然后按以下步骤完成接入:
- 安装驱动依赖:
pnpm add @prisma/adapter-mariadb(具体以项目包管理器为准); - 在
prisma.config.ts中配置datasource.url指向DATABASE_URL; - 运行
keystone dev或keystone prisma migrate dev,让 Prisma 依据 provider 生成/同步 schema; - 启动后即可通过 GraphQL API 与 Admin UI 操作 MySQL 中的数据。
结语
MySQL 的加入使 Keystone 在数据库选型上拥有 Postgres、MySQL、SQLite 三档能力:SQLite 适合本地开发与 Embedded Keystone 这类嵌入式场景,Postgres 与 MySQL 适合生产环境。切换数据库时,重点检查大小写敏感性、字段默认列类型与自增字段索引这三处行为差异,配合仓库中的 数据库选型指南 与 DB 配置文档,即可平稳迁移。
- 后端
【免费下载链接】keystone
The superpowered headless CMS for Node.js — built with GraphQL and React
相关推荐
MeterSphere多数据库支持:MySQL与PostgreSQL配置全指南
MeterSphere多数据库支持:MySQL与PostgreSQL配置全指南 引言:解决企业级测试平台的数据库选型困境 你是否正面临测试平台数据库选型的两难?
质量保障接口测试测试后端前端AI 应用DevOpsKiCad Footprint Libraries常见问题解答:解决你的封装库使用难题
KiCad Footprint Libraries常见问题解答:解决你的封装库使用难题 KiCad Footprint Libraries是KiCad版本5的官
MuJoCo 并行仿真指南:3 条路线跑通大规模批量物理模拟
MuJoCo 并行仿真指南:3 条路线跑通大规模批量物理模拟 MuJoCo 是一款通用的多关节接触物理仿真引擎,核心是把刚体、关节与接触在离散时间步里稳定求解。
物理引擎机器人机器学习图形学
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考