使用 Sync 同步 table
因為有時會出現更換 server 環境後 table 不存在情況,Sequelize 會自動 sync 寫好的 model schema 到 DB table。但要記得在初始化 server 前,引入 model,順序不同可能會產生創建
table 錯誤。
sync({force: true}) 會把表裡面的資料都刪除整個 table truncate 後重新創建 table。另外如果還沒有 table 的情況使用 sync({force: true}) 可能無法正確創建,在沒有表的時候建議使用 sync({force: false}) ,如果是修改 schema 可以用 sync({alter: true})
https://sequelize.org/docs/v7/models/model-synchronization/
程式範例:
1.創建 /database/connect.js
const { Sequelize } = require('sequelize');
const dotenv = require("dotenv"); // Import dotenv
dotenv.config(); // Load environment variables from .env file
// Initialize Sequelize with your MySQL connection details
const { DB_USER, DB_PASS, DB_HOST } = process.env;
const sequelize = new Sequelize('db_name', DB_USER, DB_PASS, {
host: DB_HOST,
dialect: 'mysql',
logging: false,
});
module.exports = sequelize;
2.創建 /database/models/user.js
const { DataTypes } = require('sequelize');
const sequelize = require('../connect');
const User = sequelize.define('User', {
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
allowNull: false,
},
createdAt: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: sequelize.literal('CURRENT_TIMESTAMP'), // Set the default value to the current timestamp
},
});
module.exports = User;
const express = require("express");
const app = express();
const sequelize = require("./database/connect.js");
// 在這裡記得引入 schema,他才會知道到要創 table
require("./database/models/user");
require("./database/models/userReward");
async function initDatabase() {
try {
await sequelize.authenticate();
await sequelize.sync({ force: false }); // {alter: true}
console.log("Database synced")
// Additional model-related initialization can go here
} catch (err) {
console.error('Failed to initialize database:', err);
throw err;
}
}
const initRoute = async () => {
const userRoute = require("./router/user");
// Router
app.use(`/user`, userRoute);
};
const server = app.listen(port, function (err) {
if (err) {
console.log(err);
} else {
console.log("Listening on port " + port);
}
});
async function main() {
try {
await initDatabase();
await initRoute()
} catch (err) {
console.error('Application initialization failed:', err);
}
}
main();
module.exports = {
server,
};
創建資料
await User.findOrCreate({
where: { user.id },
defaults: {
name: "..."
},
});
使用 Transaction
記得整段內的 find, create,update 等都要放入 transaction。
最後使用 commit 確認,或用 rollback 回覆全部狀態。
const sequelize = require("../database/connect");
const func = () => {
const transaction = await sequelize.transaction();
quote.status = "COMPLETED";
await quote.save({ transaction });
await userFBalance.save({ transaction });
await swapTx.save({ transaction });
await transaction.commit();
return swapTx;
} catch (error) {
await transaction.rollback();
throw error;
}
}
注意事項
const user = findOne() 後獲取到的 user,可以直接使用 user.name = ...,之後用 user.save(),但如果是數字不能用 user.num += ...
decimal 型態取出為 string,但存入到 decimal 時可以使用 string or number
decimal 建議指定長度,例如 type: DataTypes.DECIMAL(40, 20)
使用 transaction 時,會發生無法在 transaction 中途 create data 然後立即 access 的情況
使用 findOrCreate 獲取的 instance 無法使用 .save