Node + MSSQL - 用Sequelize和Tedious自动创建/更新SQL Server数据库

473 阅读3分钟

使用Node.jsSequelizeMS SQL Server的教程

这是一个快速的帖子,展示如何使用Sequelize和Tedious在应用程序启动时自动创建和更新(同步)SQL Server数据库。

Sequelize是一个Node.js ORM(对象关系映射器),用于连接、查询和管理关系数据库的数据。它与几个数据库兼容,包括MS SQL Server。

Tedious是一个专门针对MSSQL的数据库客户端库,用于与SQL Server的实例进行交互。它是Sequelize为MSSQL使用的底层连接器库。在下面的例子中,如果数据库不存在,它也被直接用来自动创建一个SQL Server数据库。

下面的代码片段来自我最近发布的Node.js + SQL Server CRUD API教程,关于完整的项目和如何在本地运行的说明,请看Node.js + MS SQL Server - CRUD API实例和教程

MSSQL服务器数据库封装器

MSSQL数据库包装器使用Sequelize和tedious 库连接到MSSQL。它导出了一个对象,暴露了应用程序的所有数据库模型(目前只有User ),并提供了一个简单的方法,从一个点访问数据库的任何部分。

Tedious是Sequelize用来连接到SQL Server的MSSQL连接器库。DB包装器直接使用tedious 来连接到SQL Server,如果数据库不存在,就创建它。关于乏味的更多信息见tediousjs.github.io/tedious/。

initialize() 函数在API启动时执行一次,执行以下操作。

  • 使用tedious db客户端连接到MS SQL Server,如果API数据库还不存在,则执行查询,创建API数据库。
  • 用Sequelize ORM连接到API数据库。
  • 初始化User 模型,并将其附加到导出的db 对象。
  • 通过调用await sequelize.sync({ alter: true }) ,自动创建/更新SQL Server数据库中的表以匹配Sequelize模型(如果需要)。关于Sequelize模型同步选项的更多信息见sequelize.org/master/manu…
const tedious = require('tedious');
const { Sequelize } = require('sequelize');

const { dbName, dbConfig } = require('config.json');

module.exports = db = {};

initialize();

async function initialize() {
    const dialect = 'mssql';
    const host = dbConfig.server;
    const { userName, password } = dbConfig.authentication.options;

    // create db if it doesn't already exist
    await ensureDbExists(dbName);

    // connect to db
    const sequelize = new Sequelize(dbName, userName, password, { host, dialect });

    // init models and add them to the exported db object
    db.User = require('../users/user.model')(sequelize);

    // sync all models with database
    await sequelize.sync({ alter: true });
}

async function ensureDbExists(dbName) {
    return new Promise((resolve, reject) => {
        const connection = new tedious.Connection(dbConfig);
        connection.connect((err) => {
            if (err) {
                console.error(err);
                reject(`Connection Failed: ${err.message}`);
            }

            const createDbQuery = `IF NOT EXISTS(SELECT * FROM sys.databases WHERE name = '${dbName}') CREATE DATABASE [${dbName}];`;
            const request = new tedious.Request(createDbQuery, (err) => {
                if (err) {
                    console.error(err);
                    reject(`Create DB Query Failed: ${err.message}`);
                }

                // query executed successfully
                resolve();
            });

            connection.execSql(request);
        });
    });
}

Sequelize用户模型

路径。/users/user.model.js

用户模型使用Sequelize来定义SQL Server数据库中users 表的模式。导出的Sequelize模型对象给出了在MSSQL中对用户执行CRUD(创建、读取、更新、删除)操作的完整权限。

defaultScope 将模型配置为默认从查询结果中排除密码哈希值。withHash 范围可用于查询用户并在结果中包括密码哈希。关于Sequelize作用域的更多信息,见sequelize.org/master/manu…

const { DataTypes } = require('sequelize');

module.exports = model;

function model(sequelize) {
    const attributes = {
        email: { type: DataTypes.STRING, allowNull: false },
        passwordHash: { type: DataTypes.STRING, allowNull: false },
        title: { type: DataTypes.STRING, allowNull: false },
        firstName: { type: DataTypes.STRING, allowNull: false },
        lastName: { type: DataTypes.STRING, allowNull: false },
        role: { type: DataTypes.STRING, allowNull: false }
    };

    const options = {
        defaultScope: {
            // exclude password hash by default
            attributes: { exclude: ['passwordHash'] }
        },
        scopes: {
            // include hash with this scope
            withHash: { attributes: {}, }
        }
    };

    return sequelize.define('User', attributes, options);
}