Knex.js を利用して SQLServer に接続するコードを書いて実行したところ、
Error: No event 'socketConnect' in state 'SentPrelogin'
のようなエラーが発生して接続できませんでした。
他の DB には接続できるのに SQLServer だけ接続できないのは釈然としません。
非常に困ってたのですが、同じ問題に直面している記事を見つけました。
- node.js - Error: No event 'socketConnect' in state 'SentPrelogin' - Stack Overflow
- knex/UPGRADING.md at master · knex/knex · GitHub
要するに、node-mssql だといろいろ問題があったので、Knex.js ver 0.95.0以降では直接 tedious を使うようになったそうです。
そのため、今後はnpm install mssql
ではなく、npm install tedious
にする必要があります。
当該ブロジェクトの package.json を確認したら、"knex": "^0.95.4",
だったので、
$ npm uninstall mssql $ npm install tedious
のように処理したところ、問題なく接続できました。
※Linux (KDE neon 5.21.3)と Mac (Intel macOS Mojave10.14.6)で確認済み
おまけ
当初、SQL Builder として Squel.js を利用しようとしたら、Knex.js を奨められたので、そのまま成り行きで利用してます。
ついでに、以前に書いた node-mssql を利用したコードを同じ条件で Knex.js に書き換えてみました。
const knex = require('knex')({ client: 'mssql', // ここは 'mssql' のまま connection: { server: 'localhost', user: 'sa', password: 'abcd1234$', database: 'my_test_db', options: { enableArithAbort: true, } } }); (async () => { console.log("#### Start ####"); try { console.log("-- DROP & CREATE TABLE"); await knex.schema.dropTableIfExists("会員名簿"); await knex.schema.createTable("会員名簿", table => { table.integer("番号"); table.string("氏名", 40); table.date("誕生日"); }); console.log("-- INSERT"); for (const [id, name, birthday] of [ [ 110, "岸本 龍也", "1989-11-06" ], [ 210, "荒井 伸次郎", "1974-01-30" ], [ 105, "江口 美奈", "1979-06-23" ], [ 304, "長田 隆次", "1991-05-25" ], [ 307, "中居 雄樹", "1984-02-29" ], ]) { await knex("会員名簿").insert({ "番号": id, "氏名": name, "誕生日": birthday, }); } display(await knex.select().table("会員名簿")); console.log("-- UPDATE"); const update_id = 307; const new_name = "中井 雄樹"; await knex("会員名簿").where("番号", "=", update_id) .update({ "氏名": new_name }); display( await knex.select("番号","氏名").from("会員名簿") .orderBy("番号") ); console.log("-- DELETE"); const delete_id = 210; await knex("会員名簿").where("番号", "=", delete_id).del(); display( await knex.select("番号","氏名","誕生日").from("会員名簿") .orderBy("誕生日", "desc") ); } catch (e) { console.log("#### Catch !! ####"); console.log(e); } finally { knex.destroy(); } console.log("#### Finish ####"); })() function display(rs) { let row_count = 0; if (rs.length > 0) { // カラム名 const columns = Object.keys(rs[0]); const header = []; for (const col_name of columns) { header.push(` | ${col_name}`); } header.push(" |"); console.log(header.join("")); // ロー for (const row of rs) { const buff = []; for (const col_name of columns) { buff.push(` | ${row[col_name]}`); } buff.push(" |"); console.log(buff.join("")); ++row_count; } } console.log(`結果 ${row_count} 行 (${rs.length})`); }
ソースコードの生SQL文字列を QueryBuilder / SchemaBuilder で書き換えてます。
個人的には、生SQL文字列と比較しても、あまり違和感はないかと。
検証用はともかく、新規なのに大量の埋め込みSQL文は見たくないですね。