李承武

从Strapi v3升级迁移到Strapi v4再到放弃

由于官方升级文档太一言难尽,而且自己项目基本就只用到GraphQL功能,所以自己尝试适合项目的简单升级迁移方法。

我是从v3最新版本v3.6.11升级到v4.7.1v4.8.2,理论上v3.x到v3.6期间升级版本之间没有结构性的重大变动用这方法直接升级到v4也是可行的。。。

由于在Strapi v4中REST和GraphQL响应结构的处理方式发生重大变化,意味着原来项目里所有请求和响应方式已经不适用,建议先去看看Strapi v4关于REST和GraphQL复杂响应结构的讨论,再衡量是否需要升级。

扁平化REST解决方案:strapi-plugin-transformer
扁平化GraphQL解决方案:Strapi Offcial GraphQL plugin Modify

转移api相关文件数据

首先安装个最新版本的strapi看看到底新架构是咋样的

复制一个老数据库让strapi v4生成项目时使用

发现strapi4生成数据时会清除现有数据库所有不相关的表,所以其实新建一个空数据库就可以。。。

启动项目设置好管理员后,直接使用模型构建器新建一个原项目相关字段的model

之后查看他生成的相关api文件

复制一份test目录把里面相关test字眼全部改名为原有的表feedback
再把V3项目文件\api\feedback\models\feedback.settings.json里的attributes对象复制过来

这里img字段与v3不同,用回v4的格式。你用到什么格式自己在v4生成对比一下。

尝试启动项目发现报错

Error: The key of the content-type should be the same as its singularName. Found test and feedback.

看来没有这么简单嘛,检查Strapi v4生成的数据表发现建model是有数据写入相关字段的,也就是说不能简单地新建几个文件就能自动创建并调用到数据,翻阅了一下相关文档,发现了CLI命令strapi generate

yarn strapi generate
yarn run v1.22.19
$ strapi generate
? Strapi Generators (Use arrow keys)
> api - Generate a basic API
  controller - Generate a controller for an API
  content-type - Generate a content type for an API
  plugin - Generate a basic plugin
  policy - Generate a policy for an API
  middleware - Generate a middleware for an API
  migration - Generate a migration
(Move up and down to reveal more choices)

初时使用strapi generate api生成v4的model相关文件,再把v3api\feedback\config\routes.json里的routes对象数组复制到v4有注释对应的地方

module.exports = {
  routes: [
    // {
    //  method: 'GET',
    //  path: '/feedback',
    //  handler: 'feedback.exampleAction',
    //  config: {
    //    policies: [],
    //    middlewares: [],
    //  },
    // },
  ],
};

启动发现报错

error: Error creating endpoint GET /feedbacks: Handler not found "feedback.find"

google到官方相关issues

routescontrollersservices里文件参照test生成的写法对应复制过来再把test字眼替换成feedback就成功启动了

如果你生成表后把原来数据备份复盖回生成的表里,记得添加v4新增的两个字段updated_by_idcreated_by_id,否则会有以下报错

error: select `t0`.*, `t0`.`created_by_id`, `t0`.`id`, `t0`.`updated_by_id` from `feedback` as `t0` order by `t0`.`content` ASC limit 10 - ER_BAD_FIELD_ERROR: Unknown column 't0.created_by_id' in 'field list'
Error: ER_BAD_FIELD_ERROR: Unknown column 't0.created_by_id' in 'field list'

直接使用strapi generate content-type生成modle相关文件

yarn strapi generate
yarn run v1.22.19
$ strapi generate
? Strapi Generators content-type - Generate a content type for an API
? Content type display name feedback
? Content type singular name feedback
? Content type plural name feedbacks
? Please choose the model type Collection Type
? Use draft and publish? No
? Do you want to add attributes? No
You won't be able to manage entries from the admin, you can still add attributes later from the content type builder.
? Where do you want to add this model? Add model to an existing API
? Which API is this for? feedback
? Bootstrap API related files? Yes
√  ++ \api\feedback\content-types\feedback\schema.json
√  ++ \api\feedback\routes\feedback.js
√  ++ \api\feedback\controllers\feedback.js
√  ++ \api\feedback\services\feedback.js

转移uploads相关文件数据

v3、v4的public\uploads都是一样的,复制粘贴过去即可

uploads对应的表

v3 v4
upload_file file
upload_file_morph files_related_morphs

使用Navicat导出你v3对应的表数据

在v4对应表导入,这里注意改一下从第一个数据行导入

第一个数据行改为1

对应好导入数据的相关字段并设置好主键,你哪些字段有数据就对应哪些,没有数据可以跳过
对应字段

至此其实基本没什么问题可以使用了,如果你还有很多自定义修改需要转移,可以尝试本思路并参考官网文档转移。

结语

最后我决定放弃升级到最新版本,因为在Strapi v4中,GraphQL模式的定义方式已经发生了变化。也就是说就算把请求数据返回到扁平模式,但以前v3所有定义好的Filters在v4中已经不适用,要么在所有项目上改Filters,要么自己重写v4 GraphQL定义, 尝试了两项修改对于我来说都是极度耗费时间的,并且这种修改对我来说也没什么意义,官方明显表示近期不会有任何v4回到v3格式的任何支持和过渡方案,不过不得不说Strapi v4在很多方面的确比v3优化完善了很多!

PS:严重鄙视Strapi这种对于老用户没有任何过渡方案的升级方式!!!

评论