如何在 MySql 中使用 sequelize 运行多个原始查询?

Posted

技术标签:

【中文标题】如何在 MySql 中使用 sequelize 运行多个原始查询?【英文标题】:How can I run multiple raw queries with sequelize in MySql? 【发布时间】:2014-11-21 15:22:01 【问题描述】:

我正在尝试运行一个脚本以在通过sequelize.sync( force: true ); 进行同步之前从数据库中删除所有表

当我从控制台运行脚本时,脚本运行没有问题,当我尝试从我的 node.js 应用程序运行它时会出现问题; mysql 返回解析错误。

node.js

var dropAllTables = [
    'SET FOREIGN_KEY_CHECKS = 0;',
    'SET GROUP_CONCAT_MAX_LEN = 32768;',
    'SET @tables = NULL;',
    "SELECT GROUP_CONCAT('`', table_name, '`') INTO @tables FROM information_schema.tables WHERE table_schema = (SELECT DATABASE());",
    "SET @tables = CONCAT('DROP TABLE IF EXISTS ', @tables);",
    "SELECT IFNULL(@tables, 'SELECT 1') INTO @tables;",
    'PREPARE stmt FROM @tables;',
    'EXECUTE stmt;',
    'DEALLOCATE PREPARE stmt;',
    'SET FOREIGN_KEY_CHECKS = 1;',
    "SET GLOBAL sql_mode = 'STRICT_ALL_TABLES';"
].join(' ');

sequelize.query(dropAllTables, 
    raw: true
).then(function() 
    return sequelize.sync( force: true );
).then(function() 
    console.log('Database recreated!');
    callback();
, function(err) 
    throw err;
);

错误

[Error: ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SET GROUP_CONCAT_MAX_LEN = 32768; SET @tables = NULL; SELECT GROUP_CONCAT('`', t' at line 1] code: 'ER_PARSE_ERROR', errno: 1064, sqlState: '42000', index: 0, sql: 'SET FOREIGN_KEY_CHECKS = 0; SET GROUP_CONCAT_MAX_LEN = 32768; SET @tables = NULL; SELECT GROUP_CONCAT(\'`\', table_name, \'`\') INTO @tables FROM information_schema.tables WHERE table_schema = (SELECT DATABASE()); SET @tables = CONCAT(\'DROP TABLE IF EXISTS \', @tables); SELECT IFNULL(@tables, \'SELECT 1\') INTO @tables; PREPARE stmt FROM @tables; EXECUTE stmt; DEALLOCATE PREPARE stmt; SET FOREIGN_KEY_CHECKS = 1; SET GLOBAL sql_mode = \'STRICT_ALL_TABLES\';'

我在 Google 和 sequelize docs page 中都没有发现关于使用 sequelize 的多个原始查询(我为 query 方法寻找特定参数)。

编辑:

我从 SO 克隆中找到了 this thread,人们似乎也遇到了同样的问题,但我不知道解决方案是什么。

【问题讨论】:

顺便说一下,我得到了这个工作脚本; ***.com/questions/12403662/drop-all-tables/… 【参考方案1】:

根据使用的底层mysql模块,至少mysql/mysql2支持multipleStatements: trueconnection setting。这将允许您一次发送多个查询。出于安全原因,默认情况下它被禁用。

【讨论】:

你知道将这个参数传递给底层MySql模块的正确方法是什么吗?目前我正在使用"mysql": "^2.2.0""sequelize": "^1.7.3" 我也尝试卸载mysql 模块并安装mysql2 作为测试,但它说; '你需要手动安装mysql包'。 如果你想要myql2驱动和mysql方言带sequelize可以使用dialectModulePath: 'mysql2'参数 sqlite 中的等价物是什么?【参考方案2】:

您可以使用 multipleStatements 选项传递

new Sequelize(user, pass, db, 
  dialectOptions: 
    multipleStatements: true
  
);

您放入dialectOptions 的任何内容都将传递到底层连接库(在本例中为mysql

【讨论】:

哇,谢谢你。我不敢相信它默认没有启用。 嗨@janaagaardmeier,这是否意味着我们可以在一个网络调用中发送多个SQL查询并在一个对象中获取所有这些查询的结果?如果是这样,你能指导我完成吗?我正在开发一个 NodeJS 应用程序,它有大约 12 个 SQL 查询,我希望将它们组合成 1 个或 2 个以减少网络上的数据库请求【参考方案3】:

修复使用:

  dialectOptions: 
    multipleStatements: true
  

【讨论】:

以上是关于如何在 MySql 中使用 sequelize 运行多个原始查询?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 mysql Sequelize 实例中拥有数组的数据类型?

如何使用 sequelize 和 mysql 创建一对一的关系?

如何在 sequelize 标准 createdAt 字段中使用毫秒?

如何使用 Sequelize 和 mySql 选择外键列的名称?

在 MySQL 中使用 sequelize 自动递增 id

我想用 Sequelize 将 MySQL 中的对象数组存储在单个列中