Electron and sequelize error: the dialect sqlite i

2019-03-15 21:57发布

问题:

I'm trying to use sequelize and sqlite with electron in a desktop application but get the following error when running the app via npm start (which runs node_modules/.bin/electron .):

Uncaught Error: The dialect sqlite is not supported. (Error: Please install sqlite3 package manually)

I've installed sequelize and sqlite with npm install --save sequelize sqlite. When I run the models file directly via node models.js, everything works fine:

$ node models.js
Executing (default): CREATE TABLE IF NOT EXISTS `Users` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `username` VARCHAR(255), `birthday` DATETIME, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL);
Executing (default): PRAGMA INDEX_LIST(`Users`)
Executing (default): INSERT INTO `Users` (`id`,`username`,`birthday`,`updatedAt`,`createdAt`) VALUES (NULL,'janedoe','1980-07-19 22:00:00.000 +00:00','2015-09-06 11:18:52.412 +00:00','2015-09-06 11:18:52.412 +00:00');
{ id: 1,
  username: 'janedoe',
  birthday: Sun Jul 20 1980 00:00:00 GMT+0200 (CEST),
  updatedAt: Sun Sep 06 2015 13:18:52 GMT+0200 (CEST),
  createdAt: Sun Sep 06 2015 13:18:52 GMT+0200 (CEST) }

So the problem is specific to using sequelize with electron. All files are shown below.

package.json

{
  "name": "example",
  "version": "0.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "start": "node_modules/.bin/electron .",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "devDependencies": {
    "electron-prebuilt": "^0.31.1"
  },
  "dependencies": {
    "jquery": "^2.1.4",
    "sequelize": "^3.7.1",
    "sqlite3": "^3.0.10"
  }
}

app.js

var app = require('app');
var BrowserWindow = require('browser-window');

require('crash-reporter').start();

var mainWindow = null;

app.on('window-all-closed', function() {
    if (process.platform !== 'darwin') {
        app.quit();
    }
});

app.on('ready', function() {
    mainWindow = new BrowserWindow({width: 800, height: 600});
    mainWindow.loadUrl('file://' + __dirname + '/index.html');
    mainWindow.on('closed', function() {
        mainWindow = null;
    });
});

index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <!-- Required meta tags always come first -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
    </head>
    <body>
        <p>Example</p>

        <script src="models.js"></script>
    </body>
</html>

models.js

var Sequelize = require('sequelize');
var sequelize = new Sequelize('bdgt', 'username', 'password', {
    dialect: 'sqlite',
    storage: 'example.db',
});

var User = sequelize.define('User', {
    username: Sequelize.STRING,
    birthday: Sequelize.DATE
});

sequelize.sync().then(function() {
    return User.create({
        username: 'janedoe',
        birthday: new Date(1980, 6, 20)
    });
}).then(function(jane) {
    console.log(jane.get({
        plain: true
    }));
});

Install the dependencies using npm install and reproduce the problem using npm start. Running node models.js will show sequelize works one its own.

回答1:

Finally I found a working solution to this problem, based on article provided by @Josh, and other blog posts and issue discussions. Below I wrote all steps I have taken in order to solve this problem. The final solution is posted on the bottom of this answer

I followed electron tutorial available in electron repo.

The Easy Way

I've installed electron-rebuild node package and run ./node_modules/.bin/electron-rebuild which gave me the following error:

node-pre-gyp ERR! install error 
node-pre-gyp ERR! stack Error: Unsupported target version: 0.31.2
node-pre-gyp ERR! command "node" "/my/project/dir/node_modules/sqlite3/node_modules/.bin/node-pre-gyp" "install" "--fallback-to-build"
node-pre-gyp ERR! not ok

npm ERR! Failed at the sqlite3@3.0.10 install script 'node-pre-gyp install --fallback-to-build'.
npm ERR! This is most likely a problem with the sqlite3 package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     node-pre-gyp install --fallback-to-build

The node-gyp Way

I've installed node-gyp module globally and entered ./node_modules/sqlite3 dir. Then I tried to run the following command:

node-gyp rebuild --target=0.31.2 --arch=x64 --dist-url=https://atom.io/download/atom-shell

and got the following error:

gyp: Undefined variable module_name in binding.gyp while trying to load binding.gyp

The npm Way

This resulted in the same results as The Easy Way.

The sqlite3 forks

Finally I tried to download few of the sqlite3 forks. Unfortunately results were the same.

Final attempt - The solution

The blog post provided by @Josh was forbidden for me, but I found google cached version of it. I also followed the discussion of the electron issue.

Steps presented below should get you a working sqlite3 package.

  • Change version of electron-prebuilt in your package.json "electron-prebuilt": "0.29.1"
  • Reinstall electron-prebuilt
  • Change directory into ./node_modules/sqlite3
  • Run prepublish scripts npm run prepublish
  • Configure node-gyp module_name and module_path

    node-gyp configure --module_name=node_sqlite3 --module_path=../lib/binding/node-v44-linux-x64
    
  • Rebuild package

    node-gyp rebuild --target=0.29.1 --arch=x64 --target_platform=linux --dist-url=https://atom.io/download/atom-shell --module_name=node_sqlite3 --module_path=../lib/binding/node-v44-linux-x64
    

I tried to compile using version 0.31.2 of electron-prebuilt package, but it failed for some reason.

If you are using mac replace linux with darwin.

If your os architecture is 32 bit replace x64 with ia32



回答2:

I know you have sqlite3 installed and working alone but the problem arise when you try to use sqlite3 with electron together. It's because of ABI version mismatch.

When you put a

console.log(err); in

<project>/node_modules/sequelize/lib/dialects/sqlite/connection-manager.js line 21,

just before throw new Error('Please install sqlite3 package manually'); you will see an error like following:

{ [Error: Cannot find module '<full_path_to_project>/node_modules/sqlite3/lib/binding/node-v44-linux-x64/node_sqlite3.node'] code: 'MODULE_NOT_FOUND' }

However when you check /node_modules/sqlite3/lib/binding/ folder there will be no node-v44-linux-x64 folder but something like node-v11-linux-x64 folder. (Simply renaming the folder won't work.)

This mismatch occurs because electron uses io.js v3.1.0 internally as it states here and ABI versions of it and your version of nodejs don't match.

Note that node-vXX is decided via your node's ABI version. Check this url for further info: https://github.com/mapbox/node-pre-gyp/issues/167

Solution

The easy way stated here https://github.com/atom/electron/blob/master/docs/tutorial/using-native-node-modules.md#the-easy-way doesn't work as-is with sqlite but you can follow these steps to make it work:

After installing electron-rebuild via following command

npm install --save-dev electron-rebuild

go to <project path>/node_modules/sqlite3/node_modules/node-pre-gyp/lib/util/abi_crosswalk.js and find your node version, then change node_abi value to 44. Like following:

"0.12.7": {
  "node_abi": 44,
  "v8": "3.28"
},

then give ./node_modules/.bin/electron-rebuild command and wait a bit. Then it works.



回答3:

If you can run $npm list sqlite3 and you get a response like...

MyAppName@0.0.1 /path/to/MyApp └── sqlite3@3.0.10

Then the problem is likely that sqlite3 doesn't work in Electron (without some coercing) and Sequelize doesn't know how to express the error.

See this blog post to get sqlite3 working in Electron. This should fix your issue with Sequelize.



回答4:

I've run into this error a number of times, and the solution that works for me is to install electron-rebuild, and then run:

electron-rebuild -w sqlite3 -p

The -p flag here is required for this to work, as sqlite3 uses node-pre-gyp.