1 | # egg-sequelize
|
2 |
|
3 | [Sequelize](http://sequelizejs.com) plugin for Egg.js.
|
4 |
|
5 | > NOTE: This plugin just for integrate Sequelize into Egg.js, more documentation please visit http://sequelizejs.com.
|
6 |
|
7 | [![NPM version][npm-image]][npm-url]
|
8 | [![build status][travis-image]][travis-url]
|
9 | [![Test coverage][codecov-image]][codecov-url]
|
10 | [![David deps][david-image]][david-url]
|
11 | [![Known Vulnerabilities][snyk-image]][snyk-url]
|
12 | [![npm download][download-image]][download-url]
|
13 |
|
14 | [npm-image]: https://img.shields.io/npm/v/egg-sequelize.svg?style=flat-square
|
15 | [npm-url]: https://npmjs.org/package/egg-sequelize
|
16 | [travis-image]: https://img.shields.io/travis/eggjs/egg-sequelize.svg?style=flat-square
|
17 | [travis-url]: https://travis-ci.org/eggjs/egg-sequelize
|
18 | [codecov-image]: https://codecov.io/gh/eggjs/egg-sequelize/branch/master/graph/badge.svg
|
19 | [codecov-url]: https://codecov.io/gh/eggjs/egg-sequelize
|
20 | [david-image]: https://img.shields.io/david/eggjs/egg-sequelize.svg?style=flat-square
|
21 | [david-url]: https://david-dm.org/eggjs/egg-sequelize
|
22 | [snyk-image]: https://snyk.io/test/npm/egg-sequelize/badge.svg?style=flat-square
|
23 | [snyk-url]: https://snyk.io/test/npm/egg-sequelize
|
24 | [download-image]: https://img.shields.io/npm/dm/egg-sequelize.svg?style=flat-square
|
25 | [download-url]: https://npmjs.org/package/egg-sequelize
|
26 |
|
27 | ## Install
|
28 |
|
29 | ```bash
|
30 | $ npm i --save egg-sequelize
|
31 | $ npm install --save mysql2 # For both mysql and mariadb dialects
|
32 |
|
33 | # Or use other database backend.
|
34 | $ npm install --save pg pg-hstore # PostgreSQL
|
35 | $ npm install --save tedious # MSSQL
|
36 | ```
|
37 |
|
38 |
|
39 | ## Usage & configuration
|
40 |
|
41 | - `config.default.js`
|
42 |
|
43 | ```js
|
44 | exports.sequelize = {
|
45 | dialect: 'mysql', // support: mysql, mariadb, postgres, mssql
|
46 | database: 'test',
|
47 | host: 'localhost',
|
48 | port: '3306',
|
49 | username: 'root',
|
50 | password: '',
|
51 | };
|
52 | ```
|
53 |
|
54 | - `config/plugin.js`
|
55 |
|
56 | ``` js
|
57 | exports.sequelize = {
|
58 | enable: true,
|
59 | package: 'egg-sequelize'
|
60 | }
|
61 | ```
|
62 | - `package.json`
|
63 | ```json
|
64 | {
|
65 | "scripts": {
|
66 | "migrate:new": "egg-sequelize migration:create",
|
67 | "migrate:up": "egg-sequelize db:migrate",
|
68 | "migrate:down": "egg-sequelize db:migrate:undo"
|
69 | }
|
70 | }
|
71 | ```
|
72 |
|
73 |
|
74 | More documents please refer to [Sequelize.js](http://sequelize.readthedocs.io/en/v3/)
|
75 |
|
76 | ## Model files
|
77 |
|
78 | Please put models under `app/model` dir.
|
79 |
|
80 | ## Conventions
|
81 |
|
82 | | model file | class name |
|
83 | | --------------- | --------------------- |
|
84 | | `user.js` | `app.model.User` |
|
85 | | `person.js` | `app.model.Person` |
|
86 | | `user_group.js` | `app.model.UserGroup` |
|
87 |
|
88 | - Tables always has timestamp fields: `created_at datetime`, `updated_at datetime`.
|
89 | - Use underscore style column name, for example: `user_id`, `comments_count`.
|
90 |
|
91 | ## Examples
|
92 |
|
93 | ### Standard
|
94 |
|
95 | Define a model first.
|
96 |
|
97 | > NOTE: `app.model` is an [Instance of Sequelize](http://docs.sequelizejs.com/class/lib/sequelize.js~Sequelize.html#instance-constructor-constructor), so you can use methods like: `app.model.sync, app.model.query ...`
|
98 |
|
99 | ```js
|
100 | // app/model/user.js
|
101 |
|
102 | module.exports = app => {
|
103 | const { STRING, INTEGER, DATE } = app.Sequelize;
|
104 |
|
105 | const User = app.model.define('user', {
|
106 | login: STRING,
|
107 | name: STRING(30),
|
108 | password: STRING(32),
|
109 | age: INTEGER,
|
110 | last_sign_in_at: DATE,
|
111 | created_at: DATE,
|
112 | updated_at: DATE,
|
113 | });
|
114 |
|
115 | User.findByLogin = function* (login) {
|
116 | return yield this.findOne({
|
117 | where: {
|
118 | login: login
|
119 | }
|
120 | });
|
121 | }
|
122 |
|
123 | User.prototype.logSignin = function* () {
|
124 | yield this.update({ last_sign_in_at: new Date() });
|
125 | }
|
126 |
|
127 | return User;
|
128 | };
|
129 |
|
130 | ```
|
131 |
|
132 | Now you can use it in your controller:
|
133 |
|
134 | ```js
|
135 | // app/controller/user.js
|
136 | module.exports = app => {
|
137 | return class UserController extends app.Controller {
|
138 | * index() {
|
139 | const users = yield this.ctx.model.User.findAll();
|
140 | this.ctx.body = users;
|
141 | }
|
142 |
|
143 | * show() {
|
144 | const user = yield this.ctx.model.User.findByLogin(this.ctx.params.login);
|
145 | yield user.logSignin();
|
146 | this.ctx.body = user;
|
147 | }
|
148 | }
|
149 | }
|
150 | ```
|
151 |
|
152 | ### Full example
|
153 |
|
154 | ```js
|
155 | // app/model/post.js
|
156 |
|
157 | module.exports = app => {
|
158 | const { STRING, INTEGER, DATE } = app.Sequelize;
|
159 |
|
160 | const Post = app.model.define('Post', {
|
161 | name: STRING(30),
|
162 | user_id: INTEGER,
|
163 | created_at: DATE,
|
164 | updated_at: DATE,
|
165 | });
|
166 |
|
167 | Post.associate = function() {
|
168 | app.model.Post.belongsTo(app.model.User, { as: 'user' });
|
169 | }
|
170 |
|
171 | return Post;
|
172 | };
|
173 | ```
|
174 |
|
175 |
|
176 | ```js
|
177 | // app/controller/post.js
|
178 | module.exports = app => {
|
179 | return class PostController extends app.Controller {
|
180 | * index() {
|
181 | const posts = yield this.ctx.model.Post.findAll({
|
182 | attributes: [ 'id', 'user_id' ],
|
183 | include: { model: this.ctx.model.User, as: 'user' },
|
184 | where: { status: 'publish' },
|
185 | order: 'id desc',
|
186 | });
|
187 |
|
188 | this.ctx.body = posts;
|
189 | }
|
190 |
|
191 | * show() {
|
192 | const post = yield this.ctx.model.Post.findById(this.params.id);
|
193 | const user = yield post.getUser();
|
194 | post.setDataValue('user', user);
|
195 | this.ctx.body = post;
|
196 | }
|
197 |
|
198 | * destroy() {
|
199 | const post = yield this.ctx.model.Post.findById(this.params.id);
|
200 | yield post.destroy();
|
201 | this.ctx.body = { success: true };
|
202 | }
|
203 | }
|
204 | }
|
205 | ```
|
206 |
|
207 | ## Sync model to db
|
208 |
|
209 | **We strongly recommend you to use [migrations](https://github.com/eggjs/egg-sequelize#migrations) to create or migrate database.**
|
210 |
|
211 | **This code should only be used in development.**
|
212 |
|
213 | ```js
|
214 | // {app_root}/app.js
|
215 | module.exports = app => {
|
216 | if (app.config.env === 'local') {
|
217 | app.beforeStart(function* () {
|
218 | yield app.model.sync({force: true});
|
219 | });
|
220 | }
|
221 | };
|
222 | ```
|
223 |
|
224 | ## Migrations
|
225 |
|
226 | If you have added scripts of egg-sequelize into your `package.json`, now you can:
|
227 |
|
228 | | Command | Description |
|
229 | |-----|------|
|
230 | | npm run migrate:new | Generate a new Migration file to ./migrations/ |
|
231 | | npm run migrate:up | Run Migration |
|
232 | | npm run migrate:down | Rollback once Migration |
|
233 |
|
234 | For example:
|
235 |
|
236 | ```bash
|
237 | $ npm run migrate:up
|
238 | ```
|
239 |
|
240 | For `unittest` environment:
|
241 |
|
242 | ```bash
|
243 | $ EGG_SERVER_ENV=unittest npm run migrate:up
|
244 | ```
|
245 |
|
246 | or for `prod` environment:
|
247 |
|
248 | ```bash
|
249 | $ EGG_SERVER_ENV=prod npm run migrate:up
|
250 | ```
|
251 |
|
252 | or for others environment:
|
253 |
|
254 | ```bash
|
255 | $ EGG_SERVER_ENV=pre npm run migrate:up
|
256 | ```
|
257 |
|
258 | This will load database config from `config/config.pre.js`.
|
259 |
|
260 | Write migrations with **Generator** friendly, you should use `co.wrap` method:
|
261 |
|
262 | ```js
|
263 | 'use strict';
|
264 | const co = require('co');
|
265 |
|
266 | module.exports = {
|
267 | up: co.wrap(function *(db, Sequelize) {
|
268 | const { STRING, INTEGER, DATE } = Sequelize;
|
269 |
|
270 | yield db.createTable('users', {
|
271 | id: { type: INTEGER, primaryKey: true, autoIncrement: true },
|
272 | name: { type: STRING, allowNull: false },
|
273 | email: { type: STRING, allowNull: false },
|
274 | created_at: DATE,
|
275 | updated_at: DATE,
|
276 | });
|
277 |
|
278 | yield db.addIndex('users', ['email'], { indicesType: 'UNIQUE' });
|
279 | }),
|
280 |
|
281 | down: co.wrap(function *(db, Sequelize) {
|
282 | yield db.dropTable('users');
|
283 | }),
|
284 | };
|
285 | ```
|
286 |
|
287 | And you may need to read [Sequelize - Migrations](http://docs.sequelizejs.com/manual/tutorial/migrations.html) to learn about how to write Migrations.
|
288 |
|
289 | ## Recommended example
|
290 |
|
291 | - https://github.com/eggjs/examples/tree/master/sequelize-example/
|
292 |
|
293 | ## Questions & Suggestions
|
294 |
|
295 | Please open an issue [here](https://github.com/eggjs/egg/issues).
|
296 |
|
297 | ## License
|
298 |
|
299 | [MIT](LICENSE)
|
300 |
|