Ожидал:
При создании столбца updated_ts
в table.timestamps()
его DDL должен быть:
timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
Действительный:
Часть ON UPDATE CURRENT_TIMESTAMP
отсутствует - столбец updated_ts
никогда не обновляется автоматически.
Синтаксис, который я описываю, работает для MySQL, я не уверен, насколько он совместим с механизмами баз данных.
По крайней мере, с синтаксисом postgres не все так хорошо:
http://stackoverflow.com/questions/1035980/update-timestamp-when-row-is-updated-in-postgresql
Хотя я хотел бы иметь .autoUpdate()
строителя метод timestamp
колонка, то это было бы тривиально , чтобы позволить , что за .timestamps()
помощника тоже.
Похоже, что в SQLite3 также есть триггеры, которые можно использовать для реализации этого. Oracle и mssql могут иметь более удобный синтаксис или, по крайней мере, это можно сделать с помощью триггеров.
Это было бы так здорово! в настоящее время нам нужно полагаться на то, что книжная полка обновляет наши отметки времени, верно?
Вместо того, чтобы полагаться на книжную полку, вы можете создать поля datetime вручную (mysql):
table.dateTime('created_at').notNullable().defaultTo(knex.raw('CURRENT_TIMESTAMP'))
table.dateTime('updated_at').defaultTo(knex.raw('NULL ON UPDATE CURRENT_TIMESTAMP'))
Или, если вы предпочитаете updated_at
по умолчанию для времени создания:
table.dateTime('created_at').notNullable().defaultTo(knex.raw('CURRENT_TIMESTAMP'))
table.dateTime('updated_at').notNullable().defaultTo(knex.raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'))
Вместо того, чтобы полагаться на книжную полку, вы можете создать поля datetime вручную (mysql):
table.dateTime('created_at').notNullable().defaultTo(knex.raw('CURRENT_TIMESTAMP')) table.dateTime('updated_at').defaultTo(knex.raw('NULL ON UPDATE CURRENT_TIMESTAMP'))
Использование кода, который вы опубликовали для updated_at с нулевым значением по умолчанию, по-прежнему вставляет текущую метку времени для updated_at.
const UserModel = bookshelf.Model.extend({
tableName: 'users',
hasTimestamps: ['createdAt', 'updatedAt'],
});
Этот тест не проходит:
it('doesntStoreUpdatedAtForCreation', async () => {
// arrange && act
const inserted = await new UserModel().save();
// assert
const retrievedModel = await UserModel.where({ id: inserted.id }).fetch();
assert.notExists(retrievedModel.get('updatedAt'));
});
Редактировать:
Неважно, похоже, что полное удаление hasTimestamps
из определения модели исправляет это.
Здесь мы смешиваем проблемы Knex и Bookshelf, но @ Ice32, если вы не хотите использовать функцию автоматической отметки времени Книжной полки, вам нужно удалить hasTimestamps: ['createdAt', 'updatedAt']
из определения вашей модели. Код, опубликованный выше @codeclown, будет работать
Мое решение:
const Database = use("Database");
/*......*/
table
.timestamp("created_at")
.notNullable()
.defaultTo(Database.raw("CURRENT_TIMESTAMP"));
table
.timestamp("updated_at")
.notNullable()
.defaultTo(
Database.raw("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
);
Я думаю, что timestamps()
должен либо предоставить эту функцию автоматического обновления, либо в документации необходимо явно указать, что это не так. Я просто предположил, что функциональность является важной причиной того, почему метод timestamps()
вообще существует.
Метод timestamps()
для меня бесполезен, потому что не может установить on update current_timestamp
.
Самый полезный комментарий
Я думаю, что
timestamps()
должен либо предоставить эту функцию автоматического обновления, либо в документации необходимо явно указать, что это не так. Я просто предположил, что функциональность является важной причиной того, почему методtimestamps()
вообще существует.