mirror of
https://github.com/strapi/strapi.git
synced 2025-08-01 21:36:25 +00:00
609 lines
13 KiB
Markdown
609 lines
13 KiB
Markdown
![]() |
# Migration guide from beta.17.4 through beta.17.8 to beta.18
|
||
|
|
||
|
Upgrading your Strapi application to `v3.0.0-beta.18`.
|
||
|
|
||
|
**Make sure your server is not running until the end of the migration**
|
||
|
|
||
|
## Upgrading your dependencies
|
||
|
|
||
|
Start by upgrading your dependencies. Make sure to use exact versions.
|
||
|
|
||
|
::: danger
|
||
|
Starting from beta.18 the database packages have been changed to allow future changes.
|
||
|
|
||
|
- `strapi-hook-knex` has been removed and merged into the `bookshelf` database connector.
|
||
|
- `strapi-hook-bookshelf` is renamed `strapi-connector-bookshelf`.
|
||
|
- `strapi-hook-mongoose` is renamed `strapi-connector-mongoose`.
|
||
|
|
||
|
:::
|
||
|
|
||
|
Update your package.json accordingly:
|
||
|
|
||
|
:::: tabs
|
||
|
|
||
|
::: tab bookshelf
|
||
|
|
||
|
**Before**
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
//...
|
||
|
"dependencies": {
|
||
|
"strapi": "3.0.0-beta.17.4",
|
||
|
"strapi-admin": "3.0.0-beta.17.4",
|
||
|
"strapi-hook-bookshelf": "3.0.0-beta.17.4", // rename to strapi-connector-bookshelf
|
||
|
"strapi-hook-knex": "3.0.0-beta.17.4", // remove
|
||
|
"strapi-plugin-content-manager": "3.0.0-beta.17.4",
|
||
|
"strapi-plugin-content-type-builder": "3.0.0-beta.17.4",
|
||
|
"strapi-plugin-email": "3.0.0-beta.17.4",
|
||
|
"strapi-plugin-graphql": "3.0.0-beta.17.4",
|
||
|
"strapi-plugin-upload": "3.0.0-beta.17.4",
|
||
|
"strapi-plugin-users-permissions": "3.0.0-beta.17.4",
|
||
|
"strapi-utils": "3.0.0-beta.17.4"
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
**After**
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
//...
|
||
|
"dependencies": {
|
||
|
"strapi": "3.0.0-beta.18.3",
|
||
|
"strapi-admin": "3.0.0-beta.18.3",
|
||
|
"strapi-connector-bookshelf": "3.0.0-beta.18.3",
|
||
|
"strapi-plugin-content-manager": "3.0.0-beta.18.3",
|
||
|
"strapi-plugin-content-type-builder": "3.0.0-beta.18.3",
|
||
|
"strapi-plugin-email": "3.0.0-beta.18.3",
|
||
|
"strapi-plugin-graphql": "3.0.0-beta.18.3",
|
||
|
"strapi-plugin-upload": "3.0.0-beta.18.3",
|
||
|
"strapi-plugin-users-permissions": "3.0.0-beta.18.3",
|
||
|
"strapi-utils": "3.0.0-beta.18.3"
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
:::
|
||
|
|
||
|
::: tab mongoose
|
||
|
|
||
|
**Before**
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
//...
|
||
|
"dependencies": {
|
||
|
"strapi": "3.0.0-beta.17.4",
|
||
|
"strapi-admin": "3.0.0-beta.17.4",
|
||
|
"strapi-hook-mongoose": "3.0.0-beta.17.4", // rename to strapi-connector-mongoose
|
||
|
"strapi-plugin-content-manager": "3.0.0-beta.17.4",
|
||
|
"strapi-plugin-content-type-builder": "3.0.0-beta.17.4",
|
||
|
"strapi-plugin-email": "3.0.0-beta.17.4",
|
||
|
"strapi-plugin-graphql": "3.0.0-beta.17.4",
|
||
|
"strapi-plugin-upload": "3.0.0-beta.17.4",
|
||
|
"strapi-plugin-users-permissions": "3.0.0-beta.17.4",
|
||
|
"strapi-utils": "3.0.0-beta.17.4"
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
**After**
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
//...
|
||
|
"dependencies": {
|
||
|
"strapi": "3.0.0-beta.18.3",
|
||
|
"strapi-admin": "3.0.0-beta.18.3",
|
||
|
"strapi-connector-mongoose": "3.0.0-beta.18.3",
|
||
|
"strapi-plugin-content-manager": "3.0.0-beta.18.3",
|
||
|
"strapi-plugin-content-type-builder": "3.0.0-beta.18.3",
|
||
|
"strapi-plugin-email": "3.0.0-beta.18.3",
|
||
|
"strapi-plugin-graphql": "3.0.0-beta.18.3",
|
||
|
"strapi-plugin-upload": "3.0.0-beta.18.3",
|
||
|
"strapi-plugin-users-permissions": "3.0.0-beta.18.3",
|
||
|
"strapi-utils": "3.0.0-beta.18.3"
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
:::
|
||
|
|
||
|
::::
|
||
|
|
||
|
Then run either `yarn install` or `npm install`.
|
||
|
|
||
|
## Database configuration
|
||
|
|
||
|
Now that you have installed the new database package, you need to update your `database.json` configuration files located in `./config/environments/{env}/database.json`.
|
||
|
|
||
|
You can now only use the connector name instead of the complete package name.
|
||
|
|
||
|
:::: tabs
|
||
|
|
||
|
::: tab bookshelf
|
||
|
|
||
|
**Before**
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"defaultConnection": "default",
|
||
|
"connections": {
|
||
|
"default": {
|
||
|
"connector": "strapi-hook-bookshelf",
|
||
|
"settings": {
|
||
|
//...
|
||
|
},
|
||
|
"options": {}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
**After**
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"defaultConnection": "default",
|
||
|
"connections": {
|
||
|
"default": {
|
||
|
"connector": "bookshelf",
|
||
|
"settings": {
|
||
|
//...
|
||
|
},
|
||
|
"options": {
|
||
|
//...
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
:::
|
||
|
|
||
|
::: tab mongoose
|
||
|
|
||
|
**Before**
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"defaultConnection": "default",
|
||
|
"connections": {
|
||
|
"default": {
|
||
|
"connector": "strapi-hook-mongoose",
|
||
|
"settings": {
|
||
|
//...
|
||
|
},
|
||
|
"options": {}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
**After**
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"defaultConnection": "default",
|
||
|
"connections": {
|
||
|
"default": {
|
||
|
"connector": "mongoose",
|
||
|
"settings": {
|
||
|
//...
|
||
|
},
|
||
|
"options": {
|
||
|
//...
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
:::
|
||
|
|
||
|
::::
|
||
|
|
||
|
## Adding new root page files
|
||
|
|
||
|
We have created new home pages for your api url.
|
||
|
You will need to copy `index.html` and `production.html` into your `public` folder.
|
||
|
You can find those two files [here](https://github.com/strapi/strapi/tree/master/packages/strapi-generate-new/lib/resources/files/public).
|
||
|
|
||
|
## Updating `csp` options
|
||
|
|
||
|
The admin panel contains certain assets that use `data:img;base64` images. To allow rendering of those assets you can update the files `./config/environments/{env}/security.json` as follows:
|
||
|
|
||
|
**Before**
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"csp": {
|
||
|
"enabled": true,
|
||
|
"policy": [
|
||
|
{
|
||
|
"img-src": "'self' http:"
|
||
|
},
|
||
|
"block-all-mixed-content"
|
||
|
]
|
||
|
}
|
||
|
//....
|
||
|
}
|
||
|
```
|
||
|
|
||
|
**After**
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"csp": {
|
||
|
"enabled": true,
|
||
|
"policy": ["block-all-mixed-content"]
|
||
|
}
|
||
|
//....
|
||
|
}
|
||
|
```
|
||
|
|
||
|
If you need more fine control you can also simply add the `data:` option to the `img-src` option.
|
||
|
|
||
|
## `ctx.state.user`
|
||
|
|
||
|
Previously the ctx.state.user was populated with the user informations, its role and permissions. To avoid perfromance issues the role is the only populated relation on the user by default.
|
||
|
|
||
|
## File model
|
||
|
|
||
|
The file model has been updated. The `size` field is now a decimal number, allowing correct sorting behavior.
|
||
|
|
||
|
You will need to clear some database indexes if you are using either MySQL or PostgreSQL.
|
||
|
|
||
|
:::: tabs
|
||
|
|
||
|
::: tab MySQL
|
||
|
|
||
|
Run the following statement in your database:
|
||
|
|
||
|
`DROP INDEX SEARCH_UPLOAD_FILE ON upload_file;`
|
||
|
|
||
|
:::
|
||
|
::: tab PostgreSQL
|
||
|
|
||
|
Run the following statement in your database:
|
||
|
|
||
|
`DROP INDEX search_upload_file_size;`
|
||
|
|
||
|
:::
|
||
|
::::
|
||
|
|
||
|
## Date type changes
|
||
|
|
||
|
We have introduced new types in the admin panel: `date`, `datetime` and `time`. Previously all of those types where saved as `datetime`.
|
||
|
|
||
|
You will need to change the type of your fields from `date` to `datetime` if you don't want to migrate your data.
|
||
|
|
||
|
- To migrate your old `date` to `datetime`, change the field type from `date` to `datetime`. NO data migration is required.
|
||
|
- To migrate your old `date` to new `date`, you will need to migrate your data to be of the format: `YYYY-MM-DD`
|
||
|
- To migrate your old `date` to the new `time`, change the field type from `date` to `time`. You will also need to transform them to be of the format: `HH:mm:ss.SSS`
|
||
|
|
||
|
## Groups become Components
|
||
|
|
||
|
If you were using the groups feature, you will need to apply some changes:
|
||
|
|
||
|
Start by renaming the `./groups` folder to `./components` in your project root folder.
|
||
|
|
||
|
Components now are placed into `categories`. To reflect this you must move your components inside `category` folders.
|
||
|
|
||
|
::: danger
|
||
|
Make sure to use `-` in your file names (Do not use spaces or underscores).
|
||
|
:::
|
||
|
|
||
|
### Example
|
||
|
|
||
|
**Before**
|
||
|
|
||
|
```
|
||
|
groups/
|
||
|
├── seo-metadata.json
|
||
|
└── image-text.json
|
||
|
```
|
||
|
|
||
|
**After**
|
||
|
|
||
|
```
|
||
|
components/
|
||
|
├── seo/
|
||
|
│ └── metadata.json
|
||
|
└── content/
|
||
|
└── image-text.json
|
||
|
```
|
||
|
|
||
|
Now that you have moved your component into categories. You need to update your content-types to reference them correctly.
|
||
|
|
||
|
**Before**
|
||
|
`./api/restaurant/models/Restaurant.settings.json`
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"connection": "default",
|
||
|
"collectionName": "restaurants",
|
||
|
"info": {
|
||
|
"name": "restaurant",
|
||
|
"description": ""
|
||
|
},
|
||
|
"options": {
|
||
|
"increments": true,
|
||
|
"timestamps": ["created_at", "updated_at"]
|
||
|
},
|
||
|
"attributes": {
|
||
|
"title": {
|
||
|
"type": "string"
|
||
|
},
|
||
|
"seo_metadatas": {
|
||
|
"type": "group",
|
||
|
"group": "seo-metadata",
|
||
|
"repeatable": true
|
||
|
},
|
||
|
"cover": {
|
||
|
"type": "group",
|
||
|
"group": "image-text"
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
**After**
|
||
|
`./api/restaurant/models/Restaurant.settings.json`
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"connection": "default",
|
||
|
"collectionName": "restaurants",
|
||
|
"info": {
|
||
|
"name": "restaurant",
|
||
|
"description": ""
|
||
|
},
|
||
|
"options": {
|
||
|
"increments": true,
|
||
|
"timestamps": ["created_at", "updated_at"]
|
||
|
},
|
||
|
"attributes": {
|
||
|
"title": {
|
||
|
"type": "string"
|
||
|
},
|
||
|
"seo_metadatas": {
|
||
|
"type": "component",
|
||
|
"component": "seo.metadata", // {category}.{name}
|
||
|
"repeatable": true
|
||
|
},
|
||
|
"cover": {
|
||
|
"type": "component",
|
||
|
"component": "content.image-text"
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### Database migration of groups
|
||
|
|
||
|
::: warning
|
||
|
Make sure to do a database backup before your migration.
|
||
|
:::
|
||
|
|
||
|
Those migration are only necessary if you have data in production. Otherwise you should simply recreate your db.
|
||
|
To keep your preferences you can backup the `core_store` table data.
|
||
|
|
||
|
#### Bookshelf
|
||
|
|
||
|
Some database changes have occured:
|
||
|
|
||
|
- Component join tables have been renamed from `{content_type}_groups` to `{content_type}_components`.
|
||
|
- Component join tables column `group_type` is renamed to `component_type`.
|
||
|
- Component join tables column `group_id` is renamed to `component_id`.
|
||
|
|
||
|
**Migration queries**
|
||
|
|
||
|
Make sure to run those queries for the tables that exist in your database.
|
||
|
|
||
|
_`Queries for a Restaurant content type`_
|
||
|
:::: tabs
|
||
|
|
||
|
::: tab Sqlite
|
||
|
|
||
|
```sql
|
||
|
-- renaming the table
|
||
|
ALTER TABLE restaurants_groups
|
||
|
RENAME TO restaurants_components;
|
||
|
|
||
|
-- renaming the columns
|
||
|
ALTER TABLE restaurants_components
|
||
|
RENAME COLUMN group_type to component_type;
|
||
|
|
||
|
ALTER TABLE restaurants_components
|
||
|
RENAME COLUMN group_id to component_id;
|
||
|
```
|
||
|
|
||
|
:::
|
||
|
|
||
|
::: tab Postgres
|
||
|
|
||
|
```sql
|
||
|
-- renaming the table
|
||
|
ALTER TABLE restaurants_groups
|
||
|
RENAME TO restaurants_components;
|
||
|
|
||
|
-- renaming the columns
|
||
|
ALTER TABLE restaurants_components
|
||
|
RENAME COLUMN group_type to component_type;
|
||
|
|
||
|
ALTER TABLE restaurants_components
|
||
|
RENAME COLUMN group_id to component_id;
|
||
|
```
|
||
|
|
||
|
:::
|
||
|
|
||
|
::: tab MySQL
|
||
|
|
||
|
```sql
|
||
|
-- renaming the table
|
||
|
RENAME TABLE restaurants_groups TO restaurants_components;
|
||
|
|
||
|
|
||
|
-- renaming the columns
|
||
|
ALTER TABLE restaurants_components
|
||
|
RENAME COLUMN group_type to component_type;
|
||
|
|
||
|
ALTER TABLE restaurants_components
|
||
|
RENAME COLUMN group_id to component_id;
|
||
|
```
|
||
|
|
||
|
:::
|
||
|
|
||
|
::::
|
||
|
|
||
|
---
|
||
|
|
||
|
You might notice that you still have some tables with names containing the `group` keyword. Those are the tables that contain the groups data.
|
||
|
|
||
|
If you want to rename them you have 3 steps to follow:
|
||
|
|
||
|
**1. Rename the table in your DB (you can use the table renaming query shown above).**
|
||
|
|
||
|
:::: tabs
|
||
|
::: tab Sqlite
|
||
|
|
||
|
```sql
|
||
|
ALTER TABLE groups_old_table_name
|
||
|
RENAME TO components_new_table_name;
|
||
|
```
|
||
|
|
||
|
:::
|
||
|
::: tab Postgres
|
||
|
|
||
|
```sql
|
||
|
ALTER TABLE groups_old_table_name
|
||
|
RENAME TO components_new_table_name;
|
||
|
```
|
||
|
|
||
|
:::
|
||
|
::: tab MySQL
|
||
|
|
||
|
```sql
|
||
|
-- renaming the table
|
||
|
RENAME TABLE groups_old_table_name TO components_new_table_name;
|
||
|
```
|
||
|
|
||
|
:::
|
||
|
::::
|
||
|
|
||
|
**2. Change the `collectionName` of the component**
|
||
|
|
||
|
**Before**
|
||
|
`./components/yourcategoryname/yourcomponentname.json`
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"collectionName": "groups_old_table_name"
|
||
|
//...
|
||
|
}
|
||
|
```
|
||
|
|
||
|
**After**
|
||
|
`./components/yourcategoryname/yourcomponentname.json`
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"collectionName": "components_new_table_name"
|
||
|
//....
|
||
|
}
|
||
|
```
|
||
|
|
||
|
**3. Update the `component_type` values in the join tables**
|
||
|
|
||
|
_Repeat this query for every join table where you are using this component._
|
||
|
|
||
|
```sql
|
||
|
UPDATE restaurant_components
|
||
|
SET component_type = 'components_new_table_name'
|
||
|
WHERE component_type = 'groups_old_table_name';
|
||
|
```
|
||
|
|
||
|
**4. If you store files in groups, update the `related_type` values**
|
||
|
|
||
|
```sql
|
||
|
UPDATE upload_file_morph
|
||
|
SET related_type = 'components_new_table_name'
|
||
|
WHERE related_type = 'groups_old_table_name';
|
||
|
```
|
||
|
|
||
|
#### Mongo
|
||
|
|
||
|
In `mongo` the relation between a content type and its components is held in an array of references. To know which component type it referes to, the array also contains a `kind` attribute containing the component Schema name.
|
||
|
|
||
|
**How to migrate**
|
||
|
|
||
|
**1. Get your new global ids**
|
||
|
|
||
|
The `kind` attribute references the Strapi `globalId` of a model. To get your component global ids run:
|
||
|
|
||
|
```sh
|
||
|
strapi console
|
||
|
```
|
||
|
|
||
|
```js
|
||
|
Object.keys(strapi.components).map(key => strapi.components[key].globalId);
|
||
|
//[
|
||
|
// 'ComponentCategoryMyComponent',
|
||
|
// 'ComponentCategoryMyOtherComponent',
|
||
|
//]
|
||
|
```
|
||
|
|
||
|
**2. Rename the component collections**
|
||
|
|
||
|
```js
|
||
|
// renaming a collection groups_my_group
|
||
|
db.collection.renameCollection('groups_my_group', 'components_my_component');
|
||
|
```
|
||
|
|
||
|
**3. Change the `collectionName` of the component**
|
||
|
|
||
|
**Before**
|
||
|
`./components/yourcategoryname/yourcomponentname.json`
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"collectionName": "groups_old_table_name"
|
||
|
//...
|
||
|
}
|
||
|
```
|
||
|
|
||
|
**After**
|
||
|
`./components/yourcategoryname/yourcomponentname.json`
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"collectionName": "components_new_table_name"
|
||
|
//....
|
||
|
}
|
||
|
```
|
||
|
|
||
|
**4. Rename the `kind` attributes**
|
||
|
|
||
|
To know the old `kind` name of a group here is the function that creates it:
|
||
|
|
||
|
```js
|
||
|
toGlobalId = name => upperFirst(camelCase(`group_${name}`));
|
||
|
// my-group => GroupMyGroup
|
||
|
```
|
||
|
|
||
|
**Query to update the kind for on filed in one contentType**:
|
||
|
|
||
|
```js
|
||
|
db.getCollection('contentTypeCollection').update(
|
||
|
{ 'componentField.kind': 'GroupsMyGroup' },
|
||
|
{ $set: { 'componentField.$.kind': 'ComponentCategoryMyComponent' } },
|
||
|
{ multi: true }
|
||
|
);
|
||
|
```
|
||
|
|
||
|
## Rebuilding your administration panel
|
||
|
|
||
|
Now delete the `.cache` and `build` folders. Then run `yarn develop`.
|