Leoric supports several timestamps:
Both createdAt
and updatedAt
are the widely received ones, which can be switched on in Sequelize with Model.init(attributes, { timestamps: true })
. deletedAt
is the one used to implement soft removal, which is automatically active if deletedAt
presents.
In the November releases, timestamps in snake cases such as created_at
and updated_at
are recognized as well.
Changes regarding query logging are as follow:
In v1.15.x versions, logQuery(sql, duration)
will return more precise duration
values, which helps performance auditing.
The breaking change will be released in v2.x, which changed from logQueryError(sql, err, duration, options)
to logQueryError(err, sql, duration, options)
, by moving the err
argument to a position that is more conventional in Node.js
Another breaking change that is scheduled in v2.x is the argument defaults of model.sync()
, which is default to model.sync({ alter: true })
in v1.x
CREATE TABLE
it isALTER TABLE
ALTER TABLE
in SQLite, it is actually carried out by replacing the table with a newly created one with new structure and original records copied, which is possible to lose data if something went wrong.Since v2.x, there will be three sync modes:
model.sync({ force })
always uses DROP TABLE IF EXISTS ...
to clear existing tables, DO NOT use in production.model.sync({ alter })
works the same as the v1.x model.sync()
.model.sync()
without force
or alter
uses CREATE TABLE
to create missing tables and skips synchronizing models with existing tables.Related changes are as below:
执行联表查询时,条件过滤一般有如下几种情况:
When carrying out JOIN queries, the WHERE conditions might be one of the following three cases:
There was an optimization to hoist the columns in WHERE clause that belong to the join target table, and have them put in subquery, then JOIN other tables on the subquery itself. This optimization might (or might not) gets better query plan, but falls short when dealing with the second case in the list above.
For example, if Post
s and Comment
s were like:
await Post.bulkCreate([
{ id: 2, title: 'Archbishop Lazarus' },
{ id: 3, title: 'Archangel Tyrael' },
]);
await Comment.bulkCreate([
{ articleId: 2, content: 'foo' },
{ articleId: 2, content: 'bar' },
{ articleId: 3, content: 'baz' },
]);
and the query condition was like below:
await Post.include('comments').order('posts.id').where({
'posts.title': { $like: 'Arch%' },
'comments.content': 'baz',
});
the generated SQL will filter records of the target table in advance, which returns insufficient result.
SELECT `posts`.*, `comments`.*
FROM (
SELECT *
FROM `articles`
WHERE `title` LIKE 'Arch%'
AND `gmt_deleted` IS NULL
LIMIT 1) AS `posts`
LEFT JOIN `comments` AS `comments`
ON `posts`.`id` = `comments`.`article_id`
AND `comments`.`gmt_deleted` IS NULL
WHERE `comments`.`content` = 'baz'
Therefore this optimization is removed in this month, to make sure correct number of rows can be fetched in any of the cases listed above.
A few issues about the .d.ts
added in October were found when testing it in real battlefield such as cnpm/cnpmcore, all of which has been persisted as test cases in test/types
false | string[]
type by @fengmk2#231There still are a few features unlisted in .d.ts
, which should be complemented in December releases.
When Model.findOne()
is unable to retrieve any record from database, either null
or undefiend
could be returned. It is changed into a more consistent way by always returning null
if nothing could be found.