不要怂,就是干,撸起袖子干!

Commit 9634338d by papb

chore: rename 'master' branch to 'main'

1 parent 2249ded1
<!-- <!--
Thanks for wanting to fix something on Sequelize - we already love you! Thanks for wanting to fix something on Sequelize - we already love you!
Please fill in the template below. Please fill in the template below.
If unsure about something, just do as best as you're able. If unsure about something, just do as best as you're able.
...@@ -15,7 +15,7 @@ _Please make sure to review and check all of these items:_ ...@@ -15,7 +15,7 @@ _Please make sure to review and check all of these items:_
- [ ] Have you added new tests to prevent regressions? - [ ] Have you added new tests to prevent regressions?
- [ ] Is a documentation update included (if this change modifies existing APIs, or introduces new ones)? - [ ] Is a documentation update included (if this change modifies existing APIs, or introduces new ones)?
- [ ] Did you update the typescript typings accordingly (if applicable)? - [ ] Did you update the typescript typings accordingly (if applicable)?
- [ ] Did you follow the commit message conventions explained in [CONTRIBUTING.md](https://github.com/sequelize/sequelize/blob/master/CONTRIBUTING.md)? - [ ] Did you follow the commit message conventions explained in [CONTRIBUTING.md](https://github.com/sequelize/sequelize/blob/main/CONTRIBUTING.md)?
<!-- NOTE: these things are not required to open a PR and can be done afterwards / while the PR is open. --> <!-- NOTE: these things are not required to open a PR and can be done afterwards / while the PR is open. -->
......
...@@ -23,7 +23,7 @@ We're glad to get pull request if any functionality is missing or something is b ...@@ -23,7 +23,7 @@ We're glad to get pull request if any functionality is missing or something is b
- Explain the issue that your PR is solving - or link to an existing issue - Explain the issue that your PR is solving - or link to an existing issue
- Make sure that all existing tests pass - Make sure that all existing tests pass
- Make sure you followed [coding guidelines](https://github.com/sequelize/sequelize/blob/master/CONTRIBUTING.md#coding-guidelines) - Make sure you followed [coding guidelines](https://github.com/sequelize/sequelize/blob/main/CONTRIBUTING.md#coding-guidelines)
- Add some tests for your new functionality or a test exhibiting the bug you are solving. Ideally all new tests should not pass _without_ your changes. - Add some tests for your new functionality or a test exhibiting the bug you are solving. Ideally all new tests should not pass _without_ your changes.
- Use [async/await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) in all new tests. Specifically this means: - Use [async/await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) in all new tests. Specifically this means:
- don't use `EventEmitter`, `QueryChainer` or the `success`, `done` and `error` events - don't use `EventEmitter`, `QueryChainer` or the `success`, `done` and `error` events
...@@ -153,18 +153,18 @@ Then push and send your pull request. Happy hacking and thank you for contributi ...@@ -153,18 +153,18 @@ Then push and send your pull request. Happy hacking and thank you for contributi
# Coding guidelines # Coding guidelines
Have a look at our [.eslintrc.json](https://github.com/sequelize/sequelize/blob/master/.eslintrc.json) file for the specifics. As part of the test process, all files will be linted, and your PR will **not** be accepted if it does not pass linting. Have a look at our [.eslintrc.json](https://github.com/sequelize/sequelize/blob/main/.eslintrc.json) file for the specifics. As part of the test process, all files will be linted, and your PR will **not** be accepted if it does not pass linting.
# Contributing to the documentation # Contributing to the documentation
For contribution guidelines for the documentation, see [CONTRIBUTING.DOCS.md](https://github.com/sequelize/sequelize/blob/master/CONTRIBUTING.DOCS.md). For contribution guidelines for the documentation, see [CONTRIBUTING.DOCS.md](https://github.com/sequelize/sequelize/blob/main/CONTRIBUTING.DOCS.md).
# Publishing a release (For Maintainers) # Publishing a release (For Maintainers)
1. Ensure that latest build on master is green 1. Ensure that latest build on the main branch is green
2. Ensure your local code is up to date (`git pull origin master`) 2. Ensure your local code is up to date (`git pull origin main`)
3. `npm version patch|minor|major` (see [Semantic Versioning](http://semver.org)) 3. `npm version patch|minor|major` (see [Semantic Versioning](http://semver.org))
4. Update changelog to match version number, commit changelog 4. Update changelog to match version number, commit changelog
5. `git push --tags origin master` 5. `git push --tags origin main`
6. `npm publish .` 6. `npm publish .`
7. Copy changelog for version to release notes for version on github 7. Copy changelog for version to release notes for version on github
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
[![npm version](https://badgen.net/npm/v/sequelize)](https://www.npmjs.com/package/sequelize) [![npm version](https://badgen.net/npm/v/sequelize)](https://www.npmjs.com/package/sequelize)
[![Build Status](https://github.com/sequelize/sequelize/workflows/CI/badge.svg)](https://github.com/sequelize/sequelize/actions?query=workflow%3ACI) [![Build Status](https://github.com/sequelize/sequelize/workflows/CI/badge.svg)](https://github.com/sequelize/sequelize/actions?query=workflow%3ACI)
[![codecov](https://badgen.net/codecov/c/github/sequelize/sequelize/master?icon=codecov)](https://codecov.io/gh/sequelize/sequelize) [![codecov](https://badgen.net/codecov/c/github/sequelize/sequelize/main?icon=codecov)](https://codecov.io/gh/sequelize/sequelize)
[![npm downloads](https://badgen.net/npm/dm/sequelize)](https://www.npmjs.com/package/sequelize) [![npm downloads](https://badgen.net/npm/dm/sequelize)](https://www.npmjs.com/package/sequelize)
[![Merged PRs](https://badgen.net/github/merged-prs/sequelize/sequelize)](https://github.com/sequelize/sequelize) [![Merged PRs](https://badgen.net/github/merged-prs/sequelize/sequelize)](https://github.com/sequelize/sequelize)
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release) [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
...@@ -13,7 +13,7 @@ New to Sequelize? Take a look at the [Tutorials and Guides](https://sequelize.or ...@@ -13,7 +13,7 @@ New to Sequelize? Take a look at the [Tutorials and Guides](https://sequelize.or
### v6 Release ### v6 Release
You can find detailed changelog [here](https://github.com/sequelize/sequelize/blob/master/docs/manual/other-topics/upgrade-to-v6.md). You can find detailed changelog [here](https://github.com/sequelize/sequelize/blob/main/docs/manual/other-topics/upgrade-to-v6.md).
## Looking for maintainers ## Looking for maintainers
Due to personal reasons a bigger part of the former core maintainers (thanks to all your hard work!) have been rather busy recently. Hence, the available time to look after our beloved ORM has been shrinking and shrinking drastically, generating a great chance for you: Due to personal reasons a bigger part of the former core maintainers (thanks to all your hard work!) have been rather busy recently. Hence, the available time to look after our beloved ORM has been shrinking and shrinking drastically, generating a great chance for you:
...@@ -39,11 +39,11 @@ $ npm i tedious # Microsoft SQL Server ...@@ -39,11 +39,11 @@ $ npm i tedious # Microsoft SQL Server
- [v6 Documentation](https://sequelize.org/master) - [v6 Documentation](https://sequelize.org/master)
- [v5/v4/v3 Documentation](https://sequelize.org) - [v5/v4/v3 Documentation](https://sequelize.org)
- [Contributing](https://github.com/sequelize/sequelize/blob/master/CONTRIBUTING.md) - [Contributing](https://github.com/sequelize/sequelize/blob/main/CONTRIBUTING.md)
## Responsible disclosure ## Responsible disclosure
If you have security issues to report, please refer to our [Responsible Disclosure Policy](https://github.com/sequelize/sequelize/blob/master/SECURITY.md) for more details. If you have security issues to report, please refer to our [Responsible Disclosure Policy](https://github.com/sequelize/sequelize/blob/main/SECURITY.md) for more details.
## Resources ## Resources
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
[![GitHub stars](https://badgen.net/github/stars/sequelize/sequelize)](https://github.com/sequelize/sequelize) [![GitHub stars](https://badgen.net/github/stars/sequelize/sequelize)](https://github.com/sequelize/sequelize)
[![Slack Status](http://sequelize-slack.herokuapp.com/badge.svg)](http://sequelize-slack.herokuapp.com/) [![Slack Status](http://sequelize-slack.herokuapp.com/badge.svg)](http://sequelize-slack.herokuapp.com/)
[![node](https://badgen.net/npm/node/sequelize)](https://www.npmjs.com/package/sequelize) [![node](https://badgen.net/npm/node/sequelize)](https://www.npmjs.com/package/sequelize)
[![License](https://badgen.net/github/license/sequelize/sequelize)](https://github.com/sequelize/sequelize/blob/master/LICENSE) [![License](https://badgen.net/github/license/sequelize/sequelize)](https://github.com/sequelize/sequelize/blob/main/LICENSE)
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release) [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
Sequelize is a promise-based Node.js [ORM](https://en.wikipedia.org/wiki/Object-relational_mapping) for [Postgres](https://en.wikipedia.org/wiki/PostgreSQL), [MySQL](https://en.wikipedia.org/wiki/MySQL), [MariaDB](https://en.wikipedia.org/wiki/MariaDB), [SQLite](https://en.wikipedia.org/wiki/SQLite) and [Microsoft SQL Server](https://en.wikipedia.org/wiki/Microsoft_SQL_Server). It features solid transaction support, relations, eager and lazy loading, read replication and more. Sequelize is a promise-based Node.js [ORM](https://en.wikipedia.org/wiki/Object-relational_mapping) for [Postgres](https://en.wikipedia.org/wiki/PostgreSQL), [MySQL](https://en.wikipedia.org/wiki/MySQL), [MariaDB](https://en.wikipedia.org/wiki/MariaDB), [SQLite](https://en.wikipedia.org/wiki/SQLite) and [Microsoft SQL Server](https://en.wikipedia.org/wiki/Microsoft_SQL_Server). It features solid transaction support, relations, eager and lazy loading, read replication and more.
......
# Model Basics # Model Basics
In this tutorial you will learn what models are in Sequelize and how to use them. In this tutorial you will learn what models are in Sequelize and how to use them.
## Concept ## Concept
Models are the essence of Sequelize. A model is an abstraction that represents a table in your database. In Sequelize, it is a class that extends [Model](../class/lib/model.js~Model.html). Models are the essence of Sequelize. A model is an abstraction that represents a table in your database. In Sequelize, it is a class that extends [Model](../class/lib/model.js~Model.html).
The model tells Sequelize several things about the entity it represents, such as the name of the table in the database and which columns it has (and their data types). The model tells Sequelize several things about the entity it represents, such as the name of the table in the database and which columns it has (and their data types).
A model in Sequelize has a name. This name does not have to be the same name of the table it represents in the database. Usually, models have singular names (such as `User`) while tables have pluralized names (such as `Users`), although this is fully configurable. A model in Sequelize has a name. This name does not have to be the same name of the table it represents in the database. Usually, models have singular names (such as `User`) while tables have pluralized names (such as `Users`), although this is fully configurable.
## Model Definition ## Model Definition
Models can be defined in two equivalent ways in Sequelize: Models can be defined in two equivalent ways in Sequelize:
* Calling [`sequelize.define(modelName, attributes, options)`](../class/lib/sequelize.js~Sequelize.html#instance-method-define) * Calling [`sequelize.define(modelName, attributes, options)`](../class/lib/sequelize.js~Sequelize.html#instance-method-define)
* Extending [Model](../class/lib/model.js~Model.html) and calling [`init(attributes, options)`](../class/lib/model.js~Model.html#static-method-init) * Extending [Model](../class/lib/model.js~Model.html) and calling [`init(attributes, options)`](../class/lib/model.js~Model.html#static-method-init)
After a model is defined, it is available within `sequelize.models` by its model name. After a model is defined, it is available within `sequelize.models` by its model name.
To learn with an example, we will consider that we want to create a model to represent users, which have a `firstName` and a `lastName`. We want our model to be called `User`, and the table it represents is called `Users` in the database. To learn with an example, we will consider that we want to create a model to represent users, which have a `firstName` and a `lastName`. We want our model to be called `User`, and the table it represents is called `Users` in the database.
Both ways to define this model are shown below. After being defined, we can access our model with `sequelize.models.User`. Both ways to define this model are shown below. After being defined, we can access our model with `sequelize.models.User`.
### Using [`sequelize.define`](../class/lib/sequelize.js~Sequelize.html#instance-method-define): ### Using [`sequelize.define`](../class/lib/sequelize.js~Sequelize.html#instance-method-define):
```js ```js
const { Sequelize, DataTypes } = require('sequelize'); const { Sequelize, DataTypes } = require('sequelize');
const sequelize = new Sequelize('sqlite::memory:'); const sequelize = new Sequelize('sqlite::memory:');
const User = sequelize.define('User', { const User = sequelize.define('User', {
// Model attributes are defined here // Model attributes are defined here
firstName: { firstName: {
type: DataTypes.STRING, type: DataTypes.STRING,
allowNull: false allowNull: false
}, },
lastName: { lastName: {
type: DataTypes.STRING type: DataTypes.STRING
// allowNull defaults to true // allowNull defaults to true
} }
}, { }, {
// Other model options go here // Other model options go here
}); });
// `sequelize.define` also returns the model // `sequelize.define` also returns the model
console.log(User === sequelize.models.User); // true console.log(User === sequelize.models.User); // true
``` ```
### Extending [Model](../class/lib/model.js~Model.html) ### Extending [Model](../class/lib/model.js~Model.html)
```js ```js
const { Sequelize, DataTypes, Model } = require('sequelize'); const { Sequelize, DataTypes, Model } = require('sequelize');
const sequelize = new Sequelize('sqlite::memory'); const sequelize = new Sequelize('sqlite::memory');
class User extends Model {} class User extends Model {}
User.init({ User.init({
// Model attributes are defined here // Model attributes are defined here
firstName: { firstName: {
type: DataTypes.STRING, type: DataTypes.STRING,
allowNull: false allowNull: false
}, },
lastName: { lastName: {
type: DataTypes.STRING type: DataTypes.STRING
// allowNull defaults to true // allowNull defaults to true
} }
}, { }, {
// Other model options go here // Other model options go here
sequelize, // We need to pass the connection instance sequelize, // We need to pass the connection instance
modelName: 'User' // We need to choose the model name modelName: 'User' // We need to choose the model name
}); });
// the defined model is the class itself // the defined model is the class itself
console.log(User === sequelize.models.User); // true console.log(User === sequelize.models.User); // true
``` ```
Internally, `sequelize.define` calls `Model.init`, so both approaches are essentially equivalent. Internally, `sequelize.define` calls `Model.init`, so both approaches are essentially equivalent.
## Table name inference ## Table name inference
Observe that, in both methods above, the table name (`Users`) was never explicitly defined. However, the model name was given (`User`). Observe that, in both methods above, the table name (`Users`) was never explicitly defined. However, the model name was given (`User`).
By default, when the table name is not given, Sequelize automatically pluralizes the model name and uses that as the table name. This pluralization is done under the hood by a library called [inflection](https://www.npmjs.com/package/inflection), so that irregular plurals (such as `person -> people`) are computed correctly. By default, when the table name is not given, Sequelize automatically pluralizes the model name and uses that as the table name. This pluralization is done under the hood by a library called [inflection](https://www.npmjs.com/package/inflection), so that irregular plurals (such as `person -> people`) are computed correctly.
Of course, this behavior is easily configurable. Of course, this behavior is easily configurable.
### Enforcing the table name to be equal to the model name ### Enforcing the table name to be equal to the model name
You can stop the auto-pluralization performed by Sequelize using the `freezeTableName: true` option. This way, Sequelize will infer the table name to be equal to the model name, without any modifications: You can stop the auto-pluralization performed by Sequelize using the `freezeTableName: true` option. This way, Sequelize will infer the table name to be equal to the model name, without any modifications:
```js ```js
sequelize.define('User', { sequelize.define('User', {
// ... (attributes) // ... (attributes)
}, { }, {
freezeTableName: true freezeTableName: true
}); });
``` ```
The example above will create a model named `User` pointing to a table also named `User`. The example above will create a model named `User` pointing to a table also named `User`.
This behavior can also be defined globally for the sequelize instance, when it is created: This behavior can also be defined globally for the sequelize instance, when it is created:
```js ```js
const sequelize = new Sequelize('sqlite::memory:', { const sequelize = new Sequelize('sqlite::memory:', {
define: { define: {
freezeTableName: true freezeTableName: true
} }
}); });
``` ```
This way, all tables will use the same name as the model name. This way, all tables will use the same name as the model name.
### Providing the table name directly ### Providing the table name directly
You can simply tell Sequelize the name of the table directly as well: You can simply tell Sequelize the name of the table directly as well:
```js ```js
sequelize.define('User', { sequelize.define('User', {
// ... (attributes) // ... (attributes)
}, { }, {
tableName: 'Employees' tableName: 'Employees'
}); });
``` ```
## Model synchronization ## Model synchronization
When you define a model, you're telling Sequelize a few things about its table in the database. However, what if the table actually doesn't even exist in the database? What if it exists, but it has different columns, less columns, or any other difference? When you define a model, you're telling Sequelize a few things about its table in the database. However, what if the table actually doesn't even exist in the database? What if it exists, but it has different columns, less columns, or any other difference?
This is where model synchronization comes in. A model can be synchronized with the database by calling [`model.sync(options)`](https://sequelize.org/master/class/lib/model.js~Model.html#static-method-sync), an asynchronous function (that returns a Promise). With this call, Sequelize will automatically perform an SQL query to the database. Note that this changes only the table in the database, not the model in the JavaScript side. This is where model synchronization comes in. A model can be synchronized with the database by calling [`model.sync(options)`](https://sequelize.org/master/class/lib/model.js~Model.html#static-method-sync), an asynchronous function (that returns a Promise). With this call, Sequelize will automatically perform an SQL query to the database. Note that this changes only the table in the database, not the model in the JavaScript side.
* `User.sync()` - This creates the table if it doesn't exist (and does nothing if it already exists) * `User.sync()` - This creates the table if it doesn't exist (and does nothing if it already exists)
* `User.sync({ force: true })` - This creates the table, dropping it first if it already existed * `User.sync({ force: true })` - This creates the table, dropping it first if it already existed
* `User.sync({ alter: true })` - This checks what is the current state of the table in the database (which columns it has, what are their data types, etc), and then performs the necessary changes in the table to make it match the model. * `User.sync({ alter: true })` - This checks what is the current state of the table in the database (which columns it has, what are their data types, etc), and then performs the necessary changes in the table to make it match the model.
Example: Example:
```js ```js
await User.sync({ force: true }); await User.sync({ force: true });
console.log("The table for the User model was just (re)created!"); console.log("The table for the User model was just (re)created!");
``` ```
### Synchronizing all models at once ### Synchronizing all models at once
You can use [`sequelize.sync()`](../class/lib/sequelize.js~Sequelize.html#instance-method-sync) to automatically synchronize all models. Example: You can use [`sequelize.sync()`](../class/lib/sequelize.js~Sequelize.html#instance-method-sync) to automatically synchronize all models. Example:
```js ```js
await sequelize.sync({ force: true }); await sequelize.sync({ force: true });
console.log("All models were synchronized successfully."); console.log("All models were synchronized successfully.");
``` ```
### Dropping tables ### Dropping tables
To drop the table related to a model: To drop the table related to a model:
```js ```js
await User.drop(); await User.drop();
console.log("User table dropped!"); console.log("User table dropped!");
``` ```
To drop all tables: To drop all tables:
```js ```js
await sequelize.drop(); await sequelize.drop();
console.log("All tables dropped!"); console.log("All tables dropped!");
``` ```
### Database safety check ### Database safety check
As shown above, the `sync` and `drop` operations are destructive. Sequelize accepts a `match` option as an additional safety check, which receives a RegExp: As shown above, the `sync` and `drop` operations are destructive. Sequelize accepts a `match` option as an additional safety check, which receives a RegExp:
```js ```js
// This will run .sync() only if database name ends with '_test' // This will run .sync() only if database name ends with '_test'
sequelize.sync({ force: true, match: /_test$/ }); sequelize.sync({ force: true, match: /_test$/ });
``` ```
### Synchronization in production ### Synchronization in production
As shown above, `sync({ force: true })` and `sync({ alter: true })` can be destructive operations. Therefore, they are not recommended for production-level software. Instead, synchronization should be done with the advanced concept of [Migrations](migrations.html), with the help of the [Sequelize CLI](https://github.com/sequelize/cli). As shown above, `sync({ force: true })` and `sync({ alter: true })` can be destructive operations. Therefore, they are not recommended for production-level software. Instead, synchronization should be done with the advanced concept of [Migrations](migrations.html), with the help of the [Sequelize CLI](https://github.com/sequelize/cli).
## Timestamps ## Timestamps
By default, Sequelize automatically adds the fields `createdAt` and `updatedAt` to every model, using the data type `DataTypes.DATE`. Those fields are automatically managed as well - whenever you use Sequelize to create or update something, those fields will be set correctly. The `createdAt` field will contain the timestamp representing the moment of creation, and the `updatedAt` will contain the timestamp of the latest update. By default, Sequelize automatically adds the fields `createdAt` and `updatedAt` to every model, using the data type `DataTypes.DATE`. Those fields are automatically managed as well - whenever you use Sequelize to create or update something, those fields will be set correctly. The `createdAt` field will contain the timestamp representing the moment of creation, and the `updatedAt` will contain the timestamp of the latest update.
**Note:** This is done in the Sequelize level (i.e. not done with *SQL triggers*). This means that direct SQL queries (for example queries performed without Sequelize by any other means) will not cause these fields to be updated automatically. **Note:** This is done in the Sequelize level (i.e. not done with *SQL triggers*). This means that direct SQL queries (for example queries performed without Sequelize by any other means) will not cause these fields to be updated automatically.
This behavior can be disabled for a model with the `timestamps: false` option: This behavior can be disabled for a model with the `timestamps: false` option:
```js ```js
sequelize.define('User', { sequelize.define('User', {
// ... (attributes) // ... (attributes)
}, { }, {
timestamps: false timestamps: false
}); });
``` ```
It is also possible to enable only one of `createdAt`/`updatedAt`, and to provide a custom name for these columns: It is also possible to enable only one of `createdAt`/`updatedAt`, and to provide a custom name for these columns:
```js ```js
class Foo extends Model {} class Foo extends Model {}
Foo.init({ /* attributes */ }, { Foo.init({ /* attributes */ }, {
sequelize, sequelize,
// don't forget to enable timestamps! // don't forget to enable timestamps!
timestamps: true, timestamps: true,
// I don't want createdAt // I don't want createdAt
createdAt: false, createdAt: false,
// I want updatedAt to actually be called updateTimestamp // I want updatedAt to actually be called updateTimestamp
updatedAt: 'updateTimestamp' updatedAt: 'updateTimestamp'
}); });
``` ```
## Column declaration shorthand syntax ## Column declaration shorthand syntax
If the only thing being specified about a column is its data type, the syntax can be shortened: If the only thing being specified about a column is its data type, the syntax can be shortened:
```js ```js
// This: // This:
sequelize.define('User', { sequelize.define('User', {
name: { name: {
type: DataTypes.STRING type: DataTypes.STRING
} }
}); });
// Can be simplified to: // Can be simplified to:
sequelize.define('User', { name: DataTypes.STRING }); sequelize.define('User', { name: DataTypes.STRING });
``` ```
## Default Values ## Default Values
By default, Sequelize assumes that the default value of a column is `NULL`. This behavior can be changed by passing a specific `defaultValue` to the column definition: By default, Sequelize assumes that the default value of a column is `NULL`. This behavior can be changed by passing a specific `defaultValue` to the column definition:
```js ```js
sequelize.define('User', { sequelize.define('User', {
name: { name: {
type: DataTypes.STRING, type: DataTypes.STRING,
defaultValue: "John Doe" defaultValue: "John Doe"
} }
}); });
``` ```
Some special values, such as `Sequelize.NOW`, are also accepted: Some special values, such as `Sequelize.NOW`, are also accepted:
```js ```js
sequelize.define('Foo', { sequelize.define('Foo', {
bar: { bar: {
type: DataTypes.DATETIME, type: DataTypes.DATETIME,
defaultValue: Sequelize.NOW defaultValue: Sequelize.NOW
// This way, the current date/time will be used to populate this column (at the moment of insertion) // This way, the current date/time will be used to populate this column (at the moment of insertion)
} }
}); });
``` ```
## Data Types ## Data Types
Every column you define in your model must have a data type. Sequelize provides [a lot of built-in data types](https://github.com/sequelize/sequelize/blob/master/lib/data-types.js). To access a built-in data type, you must import `DataTypes`: Every column you define in your model must have a data type. Sequelize provides [a lot of built-in data types](https://github.com/sequelize/sequelize/blob/main/lib/data-types.js). To access a built-in data type, you must import `DataTypes`:
```js ```js
const { DataTypes } = require("sequelize"); // Import the built-in data types const { DataTypes } = require("sequelize"); // Import the built-in data types
``` ```
### Strings ### Strings
```js ```js
DataTypes.STRING // VARCHAR(255) DataTypes.STRING // VARCHAR(255)
DataTypes.STRING(1234) // VARCHAR(1234) DataTypes.STRING(1234) // VARCHAR(1234)
DataTypes.STRING.BINARY // VARCHAR BINARY DataTypes.STRING.BINARY // VARCHAR BINARY
DataTypes.TEXT // TEXT DataTypes.TEXT // TEXT
DataTypes.TEXT('tiny') // TINYTEXT DataTypes.TEXT('tiny') // TINYTEXT
DataTypes.CITEXT // CITEXT PostgreSQL and SQLite only. DataTypes.CITEXT // CITEXT PostgreSQL and SQLite only.
``` ```
### Boolean ### Boolean
```js ```js
DataTypes.BOOLEAN // TINYINT(1) DataTypes.BOOLEAN // TINYINT(1)
``` ```
### Numbers ### Numbers
```js ```js
DataTypes.INTEGER // INTEGER DataTypes.INTEGER // INTEGER
DataTypes.BIGINT // BIGINT DataTypes.BIGINT // BIGINT
DataTypes.BIGINT(11) // BIGINT(11) DataTypes.BIGINT(11) // BIGINT(11)
DataTypes.FLOAT // FLOAT DataTypes.FLOAT // FLOAT
DataTypes.FLOAT(11) // FLOAT(11) DataTypes.FLOAT(11) // FLOAT(11)
DataTypes.FLOAT(11, 10) // FLOAT(11,10) DataTypes.FLOAT(11, 10) // FLOAT(11,10)
DataTypes.REAL // REAL PostgreSQL only. DataTypes.REAL // REAL PostgreSQL only.
DataTypes.REAL(11) // REAL(11) PostgreSQL only. DataTypes.REAL(11) // REAL(11) PostgreSQL only.
DataTypes.REAL(11, 12) // REAL(11,12) PostgreSQL only. DataTypes.REAL(11, 12) // REAL(11,12) PostgreSQL only.
DataTypes.DOUBLE // DOUBLE DataTypes.DOUBLE // DOUBLE
DataTypes.DOUBLE(11) // DOUBLE(11) DataTypes.DOUBLE(11) // DOUBLE(11)
DataTypes.DOUBLE(11, 10) // DOUBLE(11,10) DataTypes.DOUBLE(11, 10) // DOUBLE(11,10)
DataTypes.DECIMAL // DECIMAL DataTypes.DECIMAL // DECIMAL
DataTypes.DECIMAL(10, 2) // DECIMAL(10,2) DataTypes.DECIMAL(10, 2) // DECIMAL(10,2)
``` ```
#### Unsigned & Zerofill integers - MySQL/MariaDB only #### Unsigned & Zerofill integers - MySQL/MariaDB only
In MySQL and MariaDB, the data types `INTEGER`, `BIGINT`, `FLOAT` and `DOUBLE` can be set as unsigned or zerofill (or both), as follows: In MySQL and MariaDB, the data types `INTEGER`, `BIGINT`, `FLOAT` and `DOUBLE` can be set as unsigned or zerofill (or both), as follows:
```js ```js
DataTypes.INTEGER.UNSIGNED DataTypes.INTEGER.UNSIGNED
DataTypes.INTEGER.ZEROFILL DataTypes.INTEGER.ZEROFILL
DataTypes.INTEGER.UNSIGNED.ZEROFILL DataTypes.INTEGER.UNSIGNED.ZEROFILL
// You can also specify the size i.e. INTEGER(10) instead of simply INTEGER // You can also specify the size i.e. INTEGER(10) instead of simply INTEGER
// Same for BIGINT, FLOAT and DOUBLE // Same for BIGINT, FLOAT and DOUBLE
``` ```
### Dates ### Dates
```js ```js
DataTypes.DATE // DATETIME for mysql / sqlite, TIMESTAMP WITH TIME ZONE for postgres DataTypes.DATE // DATETIME for mysql / sqlite, TIMESTAMP WITH TIME ZONE for postgres
DataTypes.DATE(6) // DATETIME(6) for mysql 5.6.4+. Fractional seconds support with up to 6 digits of precision DataTypes.DATE(6) // DATETIME(6) for mysql 5.6.4+. Fractional seconds support with up to 6 digits of precision
DataTypes.DATEONLY // DATE without time DataTypes.DATEONLY // DATE without time
``` ```
### UUIDs ### UUIDs
For UUIDs, use `DataTypes.UUID`. It becomes the `UUID` data type for PostgreSQL and SQLite, and `CHAR(36)` for MySQL. Sequelize can generate UUIDs automatically for these fields, simply use `Sequelize.UUIDV1` or `Sequelize.UUIDV4` as the default value: For UUIDs, use `DataTypes.UUID`. It becomes the `UUID` data type for PostgreSQL and SQLite, and `CHAR(36)` for MySQL. Sequelize can generate UUIDs automatically for these fields, simply use `Sequelize.UUIDV1` or `Sequelize.UUIDV4` as the default value:
```js ```js
{ {
type: DataTypes.UUID, type: DataTypes.UUID,
defaultValue: Sequelize.UUIDV4 // Or Sequelize.UUIDV1 defaultValue: Sequelize.UUIDV4 // Or Sequelize.UUIDV1
} }
``` ```
### Others ### Others
There are other data types, covered in a [separate guide](other-data-types.html). There are other data types, covered in a [separate guide](other-data-types.html).
## Column Options ## Column Options
When defining a column, apart from specifying the `type` of the column, and the `allowNull` and `defaultValue` options mentioned above, there are a lot more options that can be used. Some examples are below. When defining a column, apart from specifying the `type` of the column, and the `allowNull` and `defaultValue` options mentioned above, there are a lot more options that can be used. Some examples are below.
```js ```js
const { Model, DataTypes, Deferrable } = require("sequelize"); const { Model, DataTypes, Deferrable } = require("sequelize");
class Foo extends Model {} class Foo extends Model {}
Foo.init({ Foo.init({
// instantiating will automatically set the flag to true if not set // instantiating will automatically set the flag to true if not set
flag: { type: DataTypes.BOOLEAN, allowNull: false, defaultValue: true }, flag: { type: DataTypes.BOOLEAN, allowNull: false, defaultValue: true },
// default values for dates => current time // default values for dates => current time
myDate: { type: DataTypes.DATE, defaultValue: DataTypes.NOW }, myDate: { type: DataTypes.DATE, defaultValue: DataTypes.NOW },
// setting allowNull to false will add NOT NULL to the column, which means an error will be // setting allowNull to false will add NOT NULL to the column, which means an error will be
// thrown from the DB when the query is executed if the column is null. If you want to check that a value // thrown from the DB when the query is executed if the column is null. If you want to check that a value
// is not null before querying the DB, look at the validations section below. // is not null before querying the DB, look at the validations section below.
title: { type: DataTypes.STRING, allowNull: false }, title: { type: DataTypes.STRING, allowNull: false },
// Creating two objects with the same value will throw an error. The unique property can be either a // Creating two objects with the same value will throw an error. The unique property can be either a
// boolean, or a string. If you provide the same string for multiple columns, they will form a // boolean, or a string. If you provide the same string for multiple columns, they will form a
// composite unique key. // composite unique key.
uniqueOne: { type: DataTypes.STRING, unique: 'compositeIndex' }, uniqueOne: { type: DataTypes.STRING, unique: 'compositeIndex' },
uniqueTwo: { type: DataTypes.INTEGER, unique: 'compositeIndex' }, uniqueTwo: { type: DataTypes.INTEGER, unique: 'compositeIndex' },
// The unique property is simply a shorthand to create a unique constraint. // The unique property is simply a shorthand to create a unique constraint.
someUnique: { type: DataTypes.STRING, unique: true }, someUnique: { type: DataTypes.STRING, unique: true },
// Go on reading for further information about primary keys // Go on reading for further information about primary keys
identifier: { type: DataTypes.STRING, primaryKey: true }, identifier: { type: DataTypes.STRING, primaryKey: true },
// autoIncrement can be used to create auto_incrementing integer columns // autoIncrement can be used to create auto_incrementing integer columns
incrementMe: { type: DataTypes.INTEGER, autoIncrement: true }, incrementMe: { type: DataTypes.INTEGER, autoIncrement: true },
// You can specify a custom column name via the 'field' attribute: // You can specify a custom column name via the 'field' attribute:
fieldWithUnderscores: { type: DataTypes.STRING, field: 'field_with_underscores' }, fieldWithUnderscores: { type: DataTypes.STRING, field: 'field_with_underscores' },
// It is possible to create foreign keys: // It is possible to create foreign keys:
bar_id: { bar_id: {
type: DataTypes.INTEGER, type: DataTypes.INTEGER,
references: { references: {
// This is a reference to another model // This is a reference to another model
model: Bar, model: Bar,
// This is the column name of the referenced model // This is the column name of the referenced model
key: 'id', key: 'id',
// With PostgreSQL, it is optionally possible to declare when to check the foreign key constraint, passing the Deferrable type. // With PostgreSQL, it is optionally possible to declare when to check the foreign key constraint, passing the Deferrable type.
deferrable: Deferrable.INITIALLY_IMMEDIATE deferrable: Deferrable.INITIALLY_IMMEDIATE
// Options: // Options:
// - `Deferrable.INITIALLY_IMMEDIATE` - Immediately check the foreign key constraints // - `Deferrable.INITIALLY_IMMEDIATE` - Immediately check the foreign key constraints
// - `Deferrable.INITIALLY_DEFERRED` - Defer all foreign key constraint check to the end of a transaction // - `Deferrable.INITIALLY_DEFERRED` - Defer all foreign key constraint check to the end of a transaction
// - `Deferrable.NOT` - Don't defer the checks at all (default) - This won't allow you to dynamically change the rule in a transaction // - `Deferrable.NOT` - Don't defer the checks at all (default) - This won't allow you to dynamically change the rule in a transaction
} }
}, },
// Comments can only be added to columns in MySQL, MariaDB, PostgreSQL and MSSQL // Comments can only be added to columns in MySQL, MariaDB, PostgreSQL and MSSQL
commentMe: { commentMe: {
type: DataTypes.INTEGER, type: DataTypes.INTEGER,
comment: 'This is a column name that has a comment' comment: 'This is a column name that has a comment'
} }
}, { }, {
sequelize, sequelize,
modelName: 'foo', modelName: 'foo',
// Using `unique: true` in an attribute above is exactly the same as creating the index in the model's options: // Using `unique: true` in an attribute above is exactly the same as creating the index in the model's options:
indexes: [{ unique: true, fields: ['someUnique'] }] indexes: [{ unique: true, fields: ['someUnique'] }]
}); });
``` ```
## Taking advantage of Models being classes ## Taking advantage of Models being classes
The Sequelize models are [ES6 classes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes). You can very easily add custom instance or class level methods. The Sequelize models are [ES6 classes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes). You can very easily add custom instance or class level methods.
```js ```js
class User extends Model { class User extends Model {
static classLevelMethod() { static classLevelMethod() {
return 'foo'; return 'foo';
} }
instanceLevelMethod() { instanceLevelMethod() {
return 'bar'; return 'bar';
} }
getFullname() { getFullname() {
return [this.firstname, this.lastname].join(' '); return [this.firstname, this.lastname].join(' ');
} }
} }
User.init({ User.init({
firstname: Sequelize.TEXT, firstname: Sequelize.TEXT,
lastname: Sequelize.TEXT lastname: Sequelize.TEXT
}, { sequelize }); }, { sequelize });
console.log(User.classLevelMethod()); // 'foo' console.log(User.classLevelMethod()); // 'foo'
const user = User.build({ firstname: 'Jane', lastname: 'Doe' }); const user = User.build({ firstname: 'Jane', lastname: 'Doe' });
console.log(user.instanceLevelMethod()); // 'bar' console.log(user.instanceLevelMethod()); // 'bar'
console.log(user.getFullname()); // 'Jane Doe' console.log(user.getFullname()); // 'Jane Doe'
``` ```
\ No newline at end of file
...@@ -17,7 +17,7 @@ const users = await sequelize.query("SELECT * FROM `users`", { type: QueryTypes. ...@@ -17,7 +17,7 @@ const users = await sequelize.query("SELECT * FROM `users`", { type: QueryTypes.
// We didn't need to destructure the result here - the results were returned directly // We didn't need to destructure the result here - the results were returned directly
``` ```
Several other query types are available. [Peek into the source for details](https://github.com/sequelize/sequelize/blob/master/src/query-types.ts). Several other query types are available. [Peek into the source for details](https://github.com/sequelize/sequelize/blob/main/src/query-types.ts).
A second option is the model. If you pass a model the returned data will be instances of that model. A second option is the model. If you pass a model the returned data will be instances of that model.
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
## License ## License
Sequelize library is distributed with MIT license. You can find original license [here.](https://github.com/sequelize/sequelize/blob/master/LICENSE) Sequelize library is distributed with MIT license. You can find original license [here.](https://github.com/sequelize/sequelize/blob/main/LICENSE)
```text ```text
MIT License MIT License
......
...@@ -454,7 +454,7 @@ module.exports = { ...@@ -454,7 +454,7 @@ module.exports = {
dialectOptions: { dialectOptions: {
bigNumberStrings: true, bigNumberStrings: true,
ssl: { ssl: {
ca: fs.readFileSync(__dirname + '/mysql-ca-master.crt') ca: fs.readFileSync(__dirname + '/mysql-ca-main.crt')
} }
} }
} }
......
# Read Replication # Read Replication
Sequelize supports [read replication](https://en.wikipedia.org/wiki/Replication_%28computing%29#Database_replication), i.e. having multiple servers that you can connect to when you want to do a SELECT query. When you do read replication, you specify one or more servers to act as read replicas, and one server to act as the write master, which handles all writes and updates and propagates them to the replicas (note that the actual replication process is **not** handled by Sequelize, but should be set up by database backend). Sequelize supports [read replication](https://en.wikipedia.org/wiki/Replication_%28computing%29#Database_replication), i.e. having multiple servers that you can connect to when you want to do a SELECT query. When you do read replication, you specify one or more servers to act as read replicas, and one server to act as the main writer, which handles all writes and updates and propagates them to the replicas (note that the actual replication process is **not** handled by Sequelize, but should be set up by database backend).
```js ```js
const sequelize = new Sequelize('database', null, null, { const sequelize = new Sequelize('database', null, null, {
dialect: 'mysql', dialect: 'mysql',
port: 3306 port: 3306
replication: { replication: {
read: [ read: [
{ host: '8.8.8.8', username: 'read-1-username', password: process.env.READ_DB_1_PW }, { host: '8.8.8.8', username: 'read-1-username', password: process.env.READ_DB_1_PW },
{ host: '9.9.9.9', username: 'read-2-username', password: process.env.READ_DB_2_PW } { host: '9.9.9.9', username: 'read-2-username', password: process.env.READ_DB_2_PW }
], ],
write: { host: '1.1.1.1', username: 'write-username', password: process.env.WRITE_DB_PW } write: { host: '1.1.1.1', username: 'write-username', password: process.env.WRITE_DB_PW }
}, },
pool: { // If you want to override the options used for the read/write pool you can do so here pool: { // If you want to override the options used for the read/write pool you can do so here
max: 20, max: 20,
idle: 30000 idle: 30000
}, },
}) })
``` ```
If you have any general settings that apply to all replicas you do not need to provide them for each instance. In the code above, database name and port is propagated to all replicas. The same will happen for user and password, if you leave them out for any of the replicas. Each replica has the following options:`host`,`port`,`username`,`password`,`database`. If you have any general settings that apply to all replicas you do not need to provide them for each instance. In the code above, database name and port is propagated to all replicas. The same will happen for user and password, if you leave them out for any of the replicas. Each replica has the following options:`host`,`port`,`username`,`password`,`database`.
Sequelize uses a pool to manage connections to your replicas. Internally Sequelize will maintain two pools created using `pool` configuration. Sequelize uses a pool to manage connections to your replicas. Internally Sequelize will maintain two pools created using `pool` configuration.
If you want to modify these, you can pass pool as an options when instantiating Sequelize, as shown above. If you want to modify these, you can pass pool as an options when instantiating Sequelize, as shown above.
Each `write` or `useMaster: true` query will use write pool. For `SELECT` read pool will be used. Read replica are switched using a basic round robin scheduling. Each `write` or `useMaster: true` query will use write pool. For `SELECT` read pool will be used. Read replica are switched using a basic round robin scheduling.
\ No newline at end of file
...@@ -22,7 +22,7 @@ Sequelize.useCLS(namespace); ...@@ -22,7 +22,7 @@ Sequelize.useCLS(namespace);
### Database Engine Support ### Database Engine Support
We have updated our minimum supported database engine versions. Using older database engine will show `SEQUELIZE0006` deprecation warning. Please check [ENGINE.md](https://github.com/sequelize/sequelize/blob/master/ENGINE.md) for version table. We have updated our minimum supported database engine versions. Using older database engine will show `SEQUELIZE0006` deprecation warning. Please check [ENGINE.md](https://github.com/sequelize/sequelize/blob/main/ENGINE.md) for version table.
### Sequelize ### Sequelize
......
...@@ -24,7 +24,7 @@ module.exports = BaseTypes => { ...@@ -24,7 +24,7 @@ module.exports = BaseTypes => {
/** /**
* types: [hex, ...] * types: [hex, ...]
* *
* @see hex here https://github.com/tediousjs/tedious/blob/master/src/data-type.js * @see hex here https://github.com/tediousjs/tedious/blob/master/src/data-type.ts
*/ */
BaseTypes.DATE.types.mssql = [43]; BaseTypes.DATE.types.mssql = [43];
......
...@@ -99,7 +99,7 @@ class ConnectionManager extends AbstractConnectionManager { ...@@ -99,7 +99,7 @@ class ConnectionManager extends AbstractConnectionManager {
// see [http://www.postgresql.org/docs/9.3/static/runtime-config-logging.html#GUC-APPLICATION-NAME] // see [http://www.postgresql.org/docs/9.3/static/runtime-config-logging.html#GUC-APPLICATION-NAME]
'application_name', 'application_name',
// choose the SSL mode with the PGSSLMODE environment variable // choose the SSL mode with the PGSSLMODE environment variable
// object format: [https://github.com/brianc/node-postgres/blob/master/lib/connection.js#L79] // object format: [https://github.com/brianc/node-postgres/blob/ee19e74ffa6309c9c5e8e01746261a8f651661f8/lib/connection.js#L79]
// see also [http://www.postgresql.org/docs/9.3/static/libpq-ssl.html] // see also [http://www.postgresql.org/docs/9.3/static/libpq-ssl.html]
'ssl', 'ssl',
// In addition to the values accepted by the corresponding server, // In addition to the values accepted by the corresponding server,
......
...@@ -9,4 +9,4 @@ exports.noTrueLogging = deprecate(noop, 'The logging-option should be either a f ...@@ -9,4 +9,4 @@ exports.noTrueLogging = deprecate(noop, 'The logging-option should be either a f
exports.noStringOperators = deprecate(noop, 'String based operators are deprecated. Please use Symbol based operators for better security, read more at https://sequelize.org/master/manual/querying.html#operators', 'SEQUELIZE0003'); exports.noStringOperators = deprecate(noop, 'String based operators are deprecated. Please use Symbol based operators for better security, read more at https://sequelize.org/master/manual/querying.html#operators', 'SEQUELIZE0003');
exports.noBoolOperatorAliases = deprecate(noop, 'A boolean value was passed to options.operatorsAliases. This is a no-op with v5 and should be removed.', 'SEQUELIZE0004'); exports.noBoolOperatorAliases = deprecate(noop, 'A boolean value was passed to options.operatorsAliases. This is a no-op with v5 and should be removed.', 'SEQUELIZE0004');
exports.noDoubleNestedGroup = deprecate(noop, 'Passing a double nested nested array to `group` is unsupported and will be removed in v6.', 'SEQUELIZE0005'); exports.noDoubleNestedGroup = deprecate(noop, 'Passing a double nested nested array to `group` is unsupported and will be removed in v6.', 'SEQUELIZE0005');
exports.unsupportedEngine = deprecate(noop, 'This database engine version is not supported, please update your database server. More information https://github.com/sequelize/sequelize/blob/master/ENGINE.md', 'SEQUELIZE0006'); exports.unsupportedEngine = deprecate(noop, 'This database engine version is not supported, please update your database server. More information https://github.com/sequelize/sequelize/blob/main/ENGINE.md', 'SEQUELIZE0006');
...@@ -130,12 +130,12 @@ describe(Support.getTestDialectTeaser('Connection Manager'), () => { ...@@ -130,12 +130,12 @@ describe(Support.getTestDialectTeaser('Connection Manager'), () => {
it('should allow forced reads from the write pool', async () => { it('should allow forced reads from the write pool', async () => {
const master = { ...poolEntry }; const main = { ...poolEntry };
master.host = 'the-boss'; main.host = 'the-boss';
const options = { const options = {
replication: { replication: {
write: master, write: main,
read: [{ ...poolEntry }] read: [{ ...poolEntry }]
} }
}; };
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!