Sequelize 中文文檔 v4 - Model definition - 模型定義

Model definition - 模型定義

此係列文章的應用示例已發佈於 GitHub: sequelize-docs-Zh-CN. 能夠 Fork 幫助改進或 Star 關注更新. 歡迎 Star.javascript

要定義模型和表之間的映射,請使用define方法。 隨後Sequelize將自動添加createdAtupdatedAt屬性。 所以,您將可以知道數據庫條目什麼時候進入數據庫以及最後一次更新時。 若是您不想在模型上使用時間戳,只須要一些時間戳,或者您正在使用現有的數據庫,其中列被命名爲別的東西,直接跳轉到configuration以查看如何執行此操做。html

const Project = sequelize.define('project', {
  title: Sequelize.STRING,
  description: Sequelize.TEXT
})

const Task = sequelize.define('task', {
  title: Sequelize.STRING,
  description: Sequelize.TEXT,
  deadline: Sequelize.DATE
})

你還能夠在每列上進行一些設置:java

const Foo = sequelize.define('foo', {
 // 若是未賦值,則自動設置值爲 TRUE
 flag: { type: Sequelize.BOOLEAN, allowNull: false, defaultValue: true},

 // 設置默認時間爲當前時間
 myDate: { type: Sequelize.DATE, defaultValue: Sequelize.NOW },

 // 將allowNull設置爲false會將NOT NULL添加到列中,
 // 這意味着當列爲空時執行查詢時將從DB拋出錯誤。 
 // 若是要在查詢DB以前檢查值不爲空,請查看下面的驗證部分。
 title: { type: Sequelize.STRING, allowNull: false},

 // 建立具備相同值的兩個對象將拋出一個錯誤。 惟一屬性能夠是布爾值或字符串。
 // 若是爲多個列提供相同的字符串,則它們將造成複合惟一鍵。
 uniqueOne: { type: Sequelize.STRING,  unique: 'compositeIndex'},
 uniqueTwo: { type: Sequelize.INTEGER, unique: 'compositeIndex'},

 // unique屬性用來建立一個惟一約束。
 someUnique: {type: Sequelize.STRING, unique: true},
 // 這與在模型選項中建立索引徹底相同。
 {someUnique: {type: Sequelize.STRING}},
 {indexes: [{unique: true, fields: ['someUnique']}]},

 // primaryKey用於定義主鍵。
 identifier: { type: Sequelize.STRING, primaryKey: true},

 // autoIncrement可用於建立自增的整數列
 incrementMe: { type: Sequelize.INTEGER, autoIncrement: true },

 // 你能夠經過'field'屬性指定自定義字段名稱:
 fieldWithUnderscores: { type: Sequelize.STRING, field: 'field_with_underscores' },

 // 這能夠建立一個外鍵:
 bar_id: {
   type: Sequelize.INTEGER,

   references: {
     // 這是引用另外一個模型
     model: Bar,

     // 這是引用模型的列名稱
     key: 'id',

     // 這聲明何時檢查外鍵約束。 僅限PostgreSQL。
     deferrable: Sequelize.Deferrable.INITIALLY_IMMEDIATE
   }
 }
})

註釋選項也能夠在表上使用, 查看 model configurationmysql

時間戳

默認狀況下,Sequelize 會將 createdAtupdatedAt 屬性添加到模型中,以便您可以知道數據庫條目什麼時候進入數據庫以及什麼時候被更新。git

請注意,若是您使用 Sequelize 遷移,則須要將 createdAtupdatedAt 字段添加到遷移定義中:github

module.exports = {
  up(queryInterface, Sequelize) {
    return queryInterface.createTable('my-table', {
      id: {
        type: Sequelize.INTEGER,
        primaryKey: true,
        autoIncrement: true,
      },

      // 時間戳
      createdAt: Sequelize.DATE,
      updatedAt: Sequelize.DATE,
    })
  },
  down(queryInterface, Sequelize) {
    return queryInterface.dropTable('my-table');
  },
}

若是您不想在模型上使用時間戳,只須要一些時間戳記,或者您正在使用現有的數據庫,其中列被命名爲別的東西,直接跳轉到 [configuration] [0] 以查看如何執行此操做。正則表達式

數據類型

如下是 Sequelize 支持的一些數據類型。 有關完整和更新的列表, 參閱 DataTypes.sql

Sequelize.STRING                      // VARCHAR(255)
Sequelize.STRING(1234)                // VARCHAR(1234)
Sequelize.STRING.BINARY               // VARCHAR BINARY
Sequelize.TEXT                        // TEXT
Sequelize.TEXT('tiny')                // TINYTEXT

Sequelize.INTEGER                     // INTEGER
Sequelize.BIGINT                      // BIGINT
Sequelize.BIGINT(11)                  // BIGINT(11)

Sequelize.FLOAT                       // FLOAT
Sequelize.FLOAT(11)                   // FLOAT(11)
Sequelize.FLOAT(11, 12)               // FLOAT(11,12)

Sequelize.REAL                        // REAL        PostgreSQL only.
Sequelize.REAL(11)                    // REAL(11)    PostgreSQL only.
Sequelize.REAL(11, 12)                // REAL(11,12) PostgreSQL only.

Sequelize.DOUBLE                      // DOUBLE
Sequelize.DOUBLE(11)                  // DOUBLE(11)
Sequelize.DOUBLE(11, 12)              // DOUBLE(11,12)

Sequelize.DECIMAL                     // DECIMAL
Sequelize.DECIMAL(10, 2)              // DECIMAL(10,2)

Sequelize.DATE                        // DATETIME for mysql / sqlite, TIMESTAMP WITH TIME ZONE for postgres
Sequelize.DATE(6)                     // DATETIME(6) for mysql 5.6.4+. Fractional seconds support with up to 6 digits of precision
Sequelize.DATEONLY                    // DATE without time.
Sequelize.BOOLEAN                     // TINYINT(1)

Sequelize.ENUM('value 1', 'value 2')  // An ENUM with allowed values 'value 1' and 'value 2'
Sequelize.ARRAY(Sequelize.TEXT)       // Defines an array. PostgreSQL only.

Sequelize.JSON                        // JSON column. PostgreSQL only.
Sequelize.JSONB                       // JSONB column. PostgreSQL only.

Sequelize.BLOB                        // BLOB (bytea for PostgreSQL)
Sequelize.BLOB('tiny')                // TINYBLOB (bytea for PostgreSQL. Other options are medium and long)

Sequelize.UUID                        // UUID datatype for PostgreSQL and SQLite, CHAR(36) BINARY for MySQL (use defaultValue: Sequelize.UUIDV1 or Sequelize.UUIDV4 to make sequelize generate the ids automatically)

Sequelize.RANGE(Sequelize.INTEGER)    // Defines int4range range. PostgreSQL only.
Sequelize.RANGE(Sequelize.BIGINT)     // Defined int8range range. PostgreSQL only.
Sequelize.RANGE(Sequelize.DATE)       // Defines tstzrange range. PostgreSQL only.
Sequelize.RANGE(Sequelize.DATEONLY)   // Defines daterange range. PostgreSQL only.
Sequelize.RANGE(Sequelize.DECIMAL)    // Defines numrange range. PostgreSQL only.

Sequelize.ARRAY(Sequelize.RANGE(Sequelize.DATE)) // Defines array of tstzrange ranges. PostgreSQL only.

Sequelize.GEOMETRY                    // Spatial column.  PostgreSQL (with PostGIS) or MySQL only.
Sequelize.GEOMETRY('POINT')           // Spatial column with geometry type. PostgreSQL (with PostGIS) or MySQL only.
Sequelize.GEOMETRY('POINT', 4326)     // Spatial column with geometry type and SRID.  PostgreSQL (with PostGIS) or MySQL only.

BLOB數據類型容許您將數據做爲字符串和二進制插入。 當您在具備BLOB列的模型上執行find或findAll時,該數據將始終做爲二進制返回。數據庫

若是你正在使用PostgreSQL TIMESTAMP WITHOUT TIMEZONE,您須要將其解析爲不一樣的時區,請使用pg庫本身的解析器:json

require('pg').types.setTypeParser(1114, stringValue => {
  return new Date(stringValue + '+0000');
  // 例如UTC偏移。 使用你想要的任何偏移。
});

除了上述類型以外,integer,bigint,float和double也支持unsigned和zerofill屬性,能夠按任何順序組合:
請注意,這不適用於PostgreSQL!

Sequelize.INTEGER.UNSIGNED              // INTEGER UNSIGNED
Sequelize.INTEGER(11).UNSIGNED          // INTEGER(11) UNSIGNED
Sequelize.INTEGER(11).ZEROFILL          // INTEGER(11) ZEROFILL
Sequelize.INTEGER(11).ZEROFILL.UNSIGNED // INTEGER(11) UNSIGNED ZEROFILL
Sequelize.INTEGER(11).UNSIGNED.ZEROFILL // INTEGER(11) UNSIGNED ZEROFILL

上面的例子只顯示整數,可是能夠用bigint和float來完成

用對象表示法:

// 對於枚舉:
sequelize.define('model', {
  states: {
    type:   Sequelize.ENUM,
    values: ['active', 'pending', 'deleted']
  }
})

範圍類型

因爲範圍類型具備其綁定的包含(inclusive)/排除(exclusive)的額外信息,因此使用一個元組在javascript中表示它們並非很簡單。

將範圍做爲值提供時,您能夠從如下API中進行選擇:

// 默認爲 '["2016-01-01 00:00:00+00:00", "2016-02-01 00:00:00+00:00")'
// 包含下限, 排除上限
Timeline.create({ range: [new Date(Date.UTC(2016, 0, 1)), new Date(Date.UTC(2016, 1, 1))] });

// 控制包含
const range = [new Date(Date.UTC(2016, 0, 1)), new Date(Date.UTC(2016, 1, 1))];
range.inclusive = false; // '()'
range.inclusive = [false, true]; // '(]'
range.inclusive = true; // '[]'
range.inclusive = [true, false]; // '[)'

// 或做爲單個表達式
const range = [
  { value: new Date(Date.UTC(2016, 0, 1)), inclusive: false },
  { value: new Date(Date.UTC(2016, 1, 1)), inclusive: true },
];
// '("2016-01-01 00:00:00+00:00", "2016-02-01 00:00:00+00:00"]'

// 複合形式
const range = [
  { value: new Date(Date.UTC(2016, 0, 1)), inclusive: false },
  new Date(Date.UTC(2016, 1, 1)),
];
// '("2016-01-01 00:00:00+00:00", "2016-02-01 00:00:00+00:00")'

Timeline.create({ range });

不管怎樣, 請注意不管什麼時候你接收到的返回值將會是是一個範圍:

// 儲存的值: ("2016-01-01 00:00:00+00:00", "2016-02-01 00:00:00+00:00"]
range // [Date, Date]
range.inclusive // [false, true]

確保在序列化以前將其轉換爲可序列化的格式,由於數組額外的屬性將不會被序列化。

特殊狀況

// 空範圍:
Timeline.create({ range: [] }); // range = 'empty'

// 無限制範圍:
Timeline.create({ range: [null, null] }); // range = '[,)'
// range = '[,"2016-01-01 00:00:00+00:00")'
Timeline.create({ range: [null, new Date(Date.UTC(2016, 0, 1))] });

// 無窮範圍:
// range = '[-infinity,"2016-01-01 00:00:00+00:00")'
Timeline.create({ range: [-Infinity, new Date(Date.UTC(2016, 0, 1))] });

可延遲

當你在 PostgreSQL 中指定外鍵列的參數來聲明成一個可延遲類型。 可用的選項以下:

// 將全部外鍵約束檢查推遲到事務結束時。
Sequelize.Deferrable.INITIALLY_DEFERRED

// 當即檢查外鍵約束。
Sequelize.Deferrable.INITIALLY_IMMEDIATE

// 不要推遲檢查。
Sequelize.Deferrable.NOT

最後一個參數是 PostgreSQL 的默認值,不容許你在事務中動態的更改規則。 查看 the transaction section 獲取補充信息.

Getters & setters

能夠在模型上定義'對象屬性'getter和setter函數,這些能夠用於映射到數據庫字段的「保護」屬性,也能夠用於定義「僞」屬性。

Getters和Setters能夠經過兩種方式定義(您能夠混合使用這兩種方式):

  • 做爲屬性定義的一部分
  • 做爲模型參數的一部分

注意: 若是在兩個地方定義了getter或setter,那麼在相關屬性定義中找到的函數始終是優先的。

定義爲屬性定義的一部分

const Employee = sequelize.define('employee', {
  name: {
    type: Sequelize.STRING,
    allowNull: false,
    get() {
      const title = this.getDataValue('title');
      // 'this' 容許你訪問實例的屬性
      return this.getDataValue('name') + ' (' + title + ')';
    },
  },
  title: {
    type: Sequelize.STRING,
    allowNull: false,
    set(val) {
      this.setDataValue('title', val.toUpperCase());
    }
  }
});

Employee
  .create({ name: 'John Doe', title: 'senior engineer' })
  .then(employee => {
    console.log(employee.get('name')); // John Doe (SENIOR ENGINEER)
    console.log(employee.get('title')); // SENIOR ENGINEER
  })

定義爲模型參數的一部分

如下是在模型參數中定義 getter 和 setter 的示例。 fullName getter,是一個說明如何在模型上定義僞屬性的例子 - 這些屬性實際上不是數據庫模式的一部分。 事實上,僞屬性能夠經過兩種方式定義:使用模型getter,或者使用虛擬數據類型的列。 虛擬數據類型能夠有驗證,而虛擬屬性的getter則不能。

請注意,fullName getter函數中引用的this.firstnamethis.lastname將觸發對相應getter函數的調用。 若是你不想那樣使用getDataValue()方法來訪問原始值(見下文)。

const Foo = sequelize.define('foo', {
  firstname: Sequelize.STRING,
  lastname: Sequelize.STRING
}, {
  getterMethods: {
    fullName() {
      return this.firstname + ' ' + this.lastname
    }
  },

  setterMethods: {
    fullName(value) {
      const names = value.split(' ');

      this.setDataValue('firstname', names.slice(0, -1).join(' '));
      this.setDataValue('lastname', names.slice(-1).join(' '));
    },
  }
});

用於 getter 和 setter 定義內部的 Helper 方法

  • 檢索底層屬性值 - 老是使用 this.getDataValue()
/* 一個用於 'title' 屬性的 getter */
get() {
  return this.getDataValue('title')
}
  • 設置基礎屬性值 - 老是使用 this.setDataValue()
/* 一個用於 'title' 屬性的 setter */
set(title) {
  this.setDataValue('title', title.toString().toLowerCase());
}

注意: 堅持使用 setDataValue()getDataValue() 函數(而不是直接訪問底層的「數據值」屬性)是很是重要的 - 這樣作能夠保護您的定製getter和setter不受底層模型實現的變化。

驗證

模型驗證,容許您爲模型的每一個屬性指定格式/內容/繼承驗證。

驗證會自動運行在 createupdatesave 上。 你也能夠調用 validate() 手動驗證一個實例。

驗證由 validator.js 實現。

const ValidateMe = sequelize.define('foo', {
  foo: {
    type: Sequelize.STRING,
    validate: {
      is: ["^[a-z]+$",'i'],     // 只容許字母
      is: /^[a-z]+$/i,          // 與上一個示例相同,使用了真正的正則表達式
      not: ["[a-z]",'i'],       // 不容許字母
      isEmail: true,            // 檢查郵件格式 (foo@bar.com)
      isUrl: true,              // 檢查鏈接格式 (http://foo.com)
      isIP: true,               // 檢查 IPv4 (129.89.23.1) 或 IPv6 格式
      isIPv4: true,             // 檢查 IPv4 (129.89.23.1) 格式
      isIPv6: true,             // 檢查 IPv6 格式
      isAlpha: true,            // 只容許字母
      isAlphanumeric: true,     // 只容許使用字母數字
      isNumeric: true,          // 只容許數字
      isInt: true,              // 檢查是否爲有效整數
      isFloat: true,            // 檢查是否爲有效浮點數
      isDecimal: true,          // 檢查是否爲任意數字
      isLowercase: true,        // 檢查是否爲小寫
      isUppercase: true,        // 檢查是否爲大寫
      notNull: true,            // 不容許爲空
      isNull: true,             // 只容許爲空
      notEmpty: true,           // 不容許空字符串
      equals: 'specific value', // 只容許一個特定值
      contains: 'foo',          // 檢查是否包含特定的子字符串
      notIn: [['foo', 'bar']],  // 檢查是否值不是其中之一
      isIn: [['foo', 'bar']],   // 檢查是否值是其中之一
      notContains: 'bar',       // 不容許包含特定的子字符串
      len: [2,10],              // 只容許長度在2到10之間的值
      isUUID: 4,                // 只容許uuids
      isDate: true,             // 只容許日期字符串
      isAfter: "2011-11-05",    // 只容許在特定日期以後的日期字符串
      isBefore: "2011-11-05",   // 只容許在特定日期以前的日期字符串
      max: 23,                  // 只容許值 <= 23
      min: 23,                  // 只容許值 >= 23
      isCreditCard: true,       // 檢查有效的信用卡號碼

      // 也能夠自定義驗證:
      isEven(value) {
        if (parseInt(value) % 2 != 0) {
          throw new Error('Only even values are allowed!')
          // 咱們也在模型的上下文中,因此若是它存在的話, 
          // this.otherField會獲得otherField的值。
        }
      }
    }
  }
});

請注意,若是須要將多個參數傳遞給內置的驗證函數,則要傳遞的參數必須位於數組中。 可是,若是要傳遞單個數組參數,例如isIn的可接受字符串數組,則將被解釋爲多個字符串參數,而不是一個數組參數。 要解決這個問題,傳遞一個單一長度的參數數組,好比[['one','two']]

要使用自定義錯誤消息而不是 validator.js 提供的錯誤消息,請使用對象而不是純值或參數數組,例如不須要參數的驗證器能夠被給定自定義消息:

isInt: {
  msg: "Must be an integer number of pennies"
}

或者若是還須要傳遞參數,請添加一個args屬性:

isIn: {
  args: [['en', 'zh']],
  msg: "Must be English or Chinese"
}

當使用自定義驗證器函數時,錯誤消息將是拋出的Error對象所持有的任何消息。

有關內置驗證方法的更多詳細信息,請參閱the validator.js project

提示: 您還能夠爲日誌記錄部分定義自定義函數。 只是傳遞一個方法。 第一個參數將是記錄的字符串。

驗證器 與 allowNull

若是模型的特定字段設置爲容許null(使用allowNull:true),而且該值已設置爲null,則其驗證器不會運行。 這意味着你能夠有一個字符串字段來驗證其長度至少爲5個字符,但也容許null

模型驗證

驗證器也能夠在特定字段驗證器以後用來定義檢查模型。例如,你能夠確保緯度經度都不設置,或者二者都設置,若是設置了一個而另外一個未設置則驗證失敗。

模型驗證器方法與模型對象的上下文一塊兒調用,若是它們拋出錯誤,則認爲失敗,不然經過。 這與自定義字段特定的驗證器同樣。

所收集的任何錯誤消息都將與驗證結果對象一塊兒放在字段驗證錯誤中,這個錯誤使用在validate參數對象中以失敗的驗證方法的鍵來命名。即使在任何一個時刻,每一個模型驗證方法只能有一個錯誤消息,它會在數組中顯示爲單個字符串錯誤,以最大化與字段錯誤的一致性。

一個例子:

const Pub = Sequelize.define('pub', {
  name: { type: Sequelize.STRING },
  address: { type: Sequelize.STRING },
  latitude: {
    type: Sequelize.INTEGER,
    allowNull: true,
    defaultValue: null,
    validate: { min: -90, max: 90 }
  },
  longitude: {
    type: Sequelize.INTEGER,
    allowNull: true,
    defaultValue: null,
    validate: { min: -180, max: 180 }
  },
}, {
  validate: {
    bothCoordsOrNone() {
      if ((this.latitude === null) !== (this.longitude === null)) {
        throw new Error('Require either both latitude and longitude or neither')
      }
    }
  }
})

在這種簡單狀況下,若是給定緯度或經度,而不是同時包含二者,則驗證失敗。 若是咱們嘗試構建一個超範圍的緯度和經度,那麼raging_bullock_arms.validate()可能會返回

{
  'latitude': ['Invalid number: latitude'],
  'bothCoordsOrNone': ['Require either both latitude and longitude or neither']
}

配置

你還能夠修改 Sequelize 處理列名稱的方式:

const Bar = sequelize.define('bar', { /* bla */ }, {
  // 不添加時間戳屬性 (updatedAt, createdAt)
  timestamps: false,

  // 不刪除數據庫條目,但將新添加的屬性deletedAt設置爲當前日期(刪除完成時)。 
  // paranoid 只有在啓用時間戳時才能工做
  paranoid: true,

  // 不使用駝峯樣式自動添加屬性,而是下劃線樣式,所以updatedAt將變爲updated_at
  underscored: true,

  // 禁用修改表名; 默認狀況下,sequelize將自動將全部傳遞的模型名稱(define的第一個參數)轉換爲複數。 若是你不想這樣,請設置如下內容
  freezeTableName: true,

  // 定義表的名稱
  tableName: 'my_very_custom_table_name',

  // 啓用樂觀鎖定。 啓用時,sequelize將向模型添加版本計數屬性,
  // 並在保存過期的實例時引起OptimisticLockingError錯誤。
  // 設置爲true或具備要用於啓用的屬性名稱的字符串。
  version: true
})

若是你但願sequelize處理時間戳,但只想要其中一部分,或者但願您的時間戳被稱爲別的東西,則能夠單獨覆蓋每一個列:

const Foo = sequelize.define('foo',  { /* bla */ }, {
  // 不要忘記啓用時間戳!
  timestamps: true,

  // 我不想要 createdAt
  createdAt: false,

  // 我想 updateAt 實際上被稱爲 updateTimestamp
  updatedAt: 'updateTimestamp',

  // 而且但願 deletedA t被稱爲 destroyTime(請記住啓用paranoid以使其工做)
  deletedAt: 'destroyTime',
  paranoid: true
})

您也能夠更改數據庫引擎,例如 變動到到MyISAM, 默認值是InnoDB。

const Person = sequelize.define('person', { /* attributes */ }, {
  engine: 'MYISAM'
})

// 或全局的
const sequelize = new Sequelize(db, user, pw, {
  define: { engine: 'MYISAM' }
})

最後,您能夠爲MySQL和PG中的表指定註釋

const Person = sequelize.define('person', { /* attributes */ }, {
  comment: "I'm a table comment!"
})

導入

您還可使用import方法將模型定義存儲在單個文件中。 返回的對象與導入文件的功能中定義的徹底相同。 因爲Sequelizev1:5.0的導入是被緩存的,因此當調用文件導入兩次或更屢次時,不會遇到問題。

// 在你的服務器文件中 - 例如 app.js
const Project = sequelize.import(__dirname + "/path/to/models/project")

// 模型已經在 /path/to/models/project.js 中定義好
// 你可能會注意到,DataTypes與上述相同
module.exports = (sequelize, DataTypes) => {
  return sequelize.define("project", {
    name: DataTypes.STRING,
    description: DataTypes.TEXT
  })
}

import方法也能夠接受回調做爲參數。

sequelize.import('project', (sequelize, DataTypes) => {
  return sequelize.define("project", {
    name: DataTypes.STRING,
    description: DataTypes.TEXT
  })
})

這個額外的功能也是有用的, 例如 Error: Cannot find module 被拋出,即便 /path/to/models/project 看起來是正確的。 一些框架,如 Meteor,重載 require,並給出「驚喜」的結果,如:

Error: Cannot find module '/home/you/meteorApp/.meteor/local/build/programs/server/app/path/to/models/project.js'

這經過傳入Meteor的require版原本解決. 因此,雖然這可能會失敗 ...

const AuthorModel = db.import('./path/to/models/project');

... 這應該是成功的 ...

const AuthorModel = db.import('project', require('./path/to/models/project'));

樂觀鎖定

Sequelize 內置支持經過模型實例版本計數的樂觀鎖定。

默認狀況下禁用樂觀鎖定,能夠經過在特定模型定義或全局模型配置中將version屬性設置爲true來啓用。 有關詳細信息,請參閱模型配置

樂觀鎖定容許併發訪問模型記錄以進行編輯,並防止衝突覆蓋數據。 它經過檢查另外一個進程是否已經讀取記錄而進行更改,並在檢測到衝突時拋出一個OptimisticLockError。

數據庫同步

當開始一個新的項目時,你還不會有一個數據庫結構,而且使用Sequelize你也不須要它。 只需指定您的模型結構,並讓庫完成其他操做。 目前支持的是建立和刪除表:

// 建立表:
Project.sync()
Task.sync()

// 強制建立!
Project.sync({force: true}) // 這將先丟棄表,而後從新建立它

// 刪除表:
Project.drop()
Task.drop()

// 事件處理:
Project.[sync|drop]().then(() => {
  // 好吧...一切都很好!
}).catch(error => {
  // oooh,你輸入了錯誤的數據庫憑據?
})

由於同步和刪除全部的表可能要寫不少行,你也可讓Sequelize來爲作這些:

// 同步全部還沒有在數據庫中的模型
sequelize.sync()

// 強制同步全部模型
sequelize.sync({force: true})

// 刪除全部表
sequelize.drop()

// 廣播處理:
sequelize.[sync|drop]().then(() => {
  // woot woot
}).catch(error => {
  // whooops
})

由於.sync({ force: true })是具備破壞性的操做,可使用match參數做爲附加的安全檢查。

match參數能夠通知Sequelize,以便在同步以前匹配正則表達式與數據庫名稱 - 在測試中使用force:true但不使用實時代碼的狀況下的安全檢查。

// 只有當數據庫名稱以'_test'結尾時,纔會運行.sync()
sequelize.sync({ force: true, match: /_test$/ });

擴展模型

Sequelize 模型是ES6類。 您能夠輕鬆添加自定義實例或類級別的方法。

const User = sequelize.define('user', { firstname: Sequelize.STRING });

// 添加一個類級別的方法
User.classLevelMethod = function() {
  return 'foo';
};

// 添加實例級別方法
User.prototype.instanceLevelMethod = function() {
  return 'bar';
};

固然,您還能夠訪問實例的數據並生成虛擬的getter:

const User = sequelize.define('user', { firstname: Sequelize.STRING, lastname: Sequelize.STRING });

User.prototype.getFullname = function() {
  return [this.firstname, this.lastname].join(' ');
};

// 例子:
User.build({ firstname: 'foo', lastname: 'bar' }).getFullname() // 'foo bar'

索引

Sequelize支持在 Model.sync()sequelize.sync 中建立的模型定義中添加索引。

sequelize.define('user', {}, {
  indexes: [
    // 在 poem 上建立一個惟一索引
    {
      unique: true,
      fields: ['poem']
    },

    // 在使用 jsonb_path_ops 的 operator 數據上建立一個 gin 索引
    {
      fields: ['data'],
      using: 'gin',
      operator: 'jsonb_path_ops'
    },

    // 默認的索引名將是 [table]_[fields]
    // 建立多列局部索引
    {
      name: 'public_by_author',
      fields: ['author', 'status'],
      where: {
        status: 'public'
      }
    },

    // 具備有序字段的BTREE索引
    {
      name: 'title_index',
      method: 'BTREE',
      fields: ['author', {attribute: 'title', collate: 'en_US', order: 'DESC', length: 5}]
    }
  ]
})

若是這篇文章對您有幫助, 感謝 下方點贊 或 Star GitHub: sequelize-docs-Zh-CN 支持, 謝謝.

相關文章
相關標籤/搜索