mirror of
				https://github.com/strapi/strapi.git
				synced 2025-10-31 18:08:11 +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 then 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`.
 | 
