javascript - SQLITE_ERROR : no such table in Node. js

标签 javascript node.js sqlite

我正在编写一个简单的服务器/客户端来跟踪用户登录的次数。用户可以创建一个帐户并将他们的计数设置为 1。后续登录将增加他们在后端 SQLITE3 中的计数数据库。

在下面的示例中,我运行了“添加”函数,该函数正确地检查用户是否已经存在,如果不存在,则将用户名、密码和 1 添加到用户表中。

正如您在输出中看到的那样,这正确地返回了 1,但为什么最后会出错?我没有进行任何其他调用,但它返回了一个 no such table 错误。我唯一调用的是 console.log(UsersModel.add('kpam', '123'));,它位于代码的最后一行。我尝试查看 events.js 的第 72 行,但它并没有真正给我太多帮助。我添加了打印语句以使其跟踪更明显,但我感觉幕后发生了什么?

基本上,我很困惑,为什么如果我只调用一个函数,并且该函数成功返回,那么在执行结束时会出现错误?

这是返回的错误:

:$ node warmup.js 
Creating DB file.
making table!
adding user!
1

events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: SQLITE_ERROR: no such table: Users
:$ 

这是我的代码:

var http = require('http');

var fs = require('fs');
var file = 'data.db';
var exists = fs.existsSync(file);

if (!exists) {
    console.log("Creating DB file.");
    fs.openSync(file, 'w');
}

var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database(file);

var UsersModel = {

    // success, no errors/problems
    SUCCESS: 1, 

    // cannot find the user/password pair in the database (for 'login' only)
    ERR_BAD_CREDENTIALS: -1,

    // trying to add a user that already exists (for 'add' only)
    ERR_USER_EXISTS: -2,

    // invalid user name (empty or longer than MAX_USERNAME_LENGTH) (for 'add'/'login')
    ERR_BAD_USERNAME: -3,

    // invalid password name (longer than MAX_PASSWORD_LENGTH) (for 'add')
    ERR_BAD_PASSWORD: -4,

    // maximum user name length
    MAX_USERNAME_LENGTH: 128,

    // maximum password length
    MAX_PASSWORD_LENGTH: 128,

    login: function(user, password) {
        if (!UsersModel.userExists(user, false)) {
            return UsersModel.ERR_BAD_CREDENTIALS;
        }

        if (!UsersModel.checkPassword(user, password)) {
            return UsersModel.ERR_BAD_CREDENTIALS;
        }

        count = UsersModel.increaseCount(user);
        return count;
    },

    add: function(user, password) {
        if (UsersModel.userExists(user, true)) {
            return UsersModel.ERR_USER_EXISTS;
        }

        if (!UsersModel.isValidUsername(user)) {
            return UsersModel.ERR_BAD_USERNAME;
        }

        if (!UsersModel.isValidPassword(password)) {
            return UsersModel.ERR_BAD_PASSWORD;
        }

        UsersModel.addUser(user, password);
        return 1;
    },

    userExists: function(user, makeTable) {
        if (!exists) {
            if (makeTable) {
                console.log('making table!');
                db.run('CREATE TABLE Users (name TEXT, password TEXT, count INT)');
            }
            return false;
        } 

        db.serialize(function() {
            console.log('checking user!');
            row = db.get("SELECT name FROM Users WHERE name = '" + user + "'");
        });

        return !(typeof(row.name) === 'undefined');
    },

    increaseCount: function(user) {
        db.serialize(function() {
            console.log('increasing count!');
            count = db.get("SELECT count FROM Users WHERE name = '" + user + "'") + 1;
            db.run("UPDATE Users SET count = '" + count + "' WHERE name = '" + user + "'");
            return count;
        });
    },

    addUser: function(user, password) {
        count = 0;
        console.log('adding user!');
        db.run("INSERT INTO Users (name, password, count) VALUES ('" + user + "','" + password + "','" + 0 + "')");
    },

    checkPassword: function(user, password) {
        db.serialize(function() {
            console.log('checking pw!');
            row = db.get("SELECT password FROM Users WHERE name = '" + user + "'");
        });

        return row.password == password;
    },

    isValidUsername: function(user) {
        return user.length < 129;
    },

    isValidPassword: function(password) {
        return password.length < 129;
    }
}

console.log(UsersModel.add('kpam', '123'));

最佳答案

db.run(...) 调用是异步的。所以他们会立即返回,并且看起来对您的代码来说是成功的。但是它们仍在后台运行。因此,SELECT 语句很可能在 CREATE TABLE 完成之前开始运行。这就是您收到该错误的原因。

我注意到 SELECT 语句在 db.serialize(...) 调用中。不幸的是,该调用仅序列化直接在其范围内的语句。序列化 block 之外的所有调用继续并行运行(这包括稍后出现的 INSERT 语句)。

您的代码需要重构以使用 Node sqlite3 模块所依赖的回调。看看这个简单的例子: https://github.com/mapbox/node-sqlite3/blob/master/examples/simple-chaining.js

注意每个数据库操作的最后一个参数是操作完成后要调用的函数的名称。

关于javascript - SQLITE_ERROR : no such table in Node. js,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21716564/

相关文章:

javascript - 如何提高由 Javascript 或 JQuery 制作的组件的速度?

javascript - 将标题和图像放在从屏幕顶部向下滑动的居中 div 中

javascript - 尽管有多个错误,但 AJV 只返回一个错误

javascript - Highchart 实时服务器示例使用大量 CPU

javascript - 使用 grunt 在文件中写入增量数字

javascript - 正则表达式只允许某些特殊字符并限制下划线

node.js - Express - 为授权/未授权用户划分的公共(public)目录

node.js - JQL查询错误: The character \'%\' is a reserved JQL character

objective-c - 在 Xcode 中访问数据库时,SQLite 不会准备查询

python - MySQL v. SQLite 用于基于 Python 的金融 Web 应用程序