使用 Knex 和 MySQL 执行多条语句(变量和迁移)

Ree*_*els 6 mysql database migration knex.js

问题:

我正在尝试向具有数千万行的表添加新列,而不阻塞它。

我知道这里有一些选项,并且我尝试了ALTER TABLENULL和默认值,但是需要很长时间(不可行)并锁定表。

因此,我尝试编写一个迁移脚本,将原始表的结构复制到新表,将新列添加到新表,然后慢慢将旧表数据迁移到新表。

我的问题是 Knex 的数据副本。

我正在本地测试,下面的查询在 Sequel Pro 的 MySQL 版本 5.6.34 中运行得非常好,但我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 '在 Knex 中得到了一个。

knex.schema.raw(`
  SELECT @prevMaxIdMovedRecord;
  SELECT @newMaxIdMovedRecord;
  SELECT maxIdMoved FROM migration_status 
    ORDER BY maxIdMoved DESC
    INTO @prevMaxIdMovedRecord;

  INSERT IGNORE INTO table_copy (field1, newField1)
  SELECT t.field1, 1 FROM table t
    WHERE t.id BETWEEN @prevMaxIdMovedRecord AND @prevMaxIdMovedRecord + 50000;

  SELECT id FROM table_copy
    ORDER BY id DESC
    LIMIT 1
    INTO @newMaxIdMovedRecord;

  INSERT INTO migration_status (maxIdMoved)
    VALUES (@newMaxIdMovedRecord);

  DELIMITER ;
`)
Run Code Online (Sandbox Code Playgroud)

这里有专家可以提供帮助吗?我看不到 Knex 允许您在 Knexfile.js 中指定 MySQL 版本,我想知道版本之间是否存在语法不匹配。我在新表等方面的所有其他命令都工作正常......

谢谢

Ric*_*her 6

默认情况下,mysql 驱动程序不接受单个查询中的多个语句。您可以使用一个简单的 Node 程序来演示这一点:

const mysql = require('mysql')

connection = mysql.createConnection({
    host: 'localhost',
    user: 'youruser',
    password: 'yourpassword',
    database: 'yourdb',
    multipleStatements: true
})
connection.connect()

connection.query('SELECT 1+1; SELECT 2+2;', function(err, results) {
    if (err) {
        throw err
    }

    console.log(results[0], results[1])
})

connection.end()
Run Code Online (Sandbox Code Playgroud)

如果设置multipleStatementsfalse,您应该会看到错误。虽然multipleStatements可以通过您的 传递给驱动程序knexfile.js

 {
    client: "mysql",
    connection: {
        // ... other options ...
        multipleStatements: true
    }
}
Run Code Online (Sandbox Code Playgroud)

你可以尝试这个,我建议你使用事务,因为在一个大表上执行一个查询中的多个语句似乎很脆弱。请参阅文档了解介绍。