NodeJS MySQL转储 [英] NodeJS MySQL Dump

查看:64
本文介绍了NodeJS MySQL转储的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图编写一个基本的cron脚本来运行和转储"一个mysql数据库.由于某种原因,当成功保存文件"时,它会创建文件,但是它为空.如果执行保存console.log而不是保存文件,它将打印一个空字符串.对我可能做错的事情有任何想法吗?

I've attempted to write a basic cron script to run and 'dump' a mysql database. For some reason, when it 'successfully saves the file', it does create the file, but it is empty. If instead of saving the file, I perform a console.log, it prints an empty string. Any thoughts on what I may be doing wrong?

谢谢.

var mysql_backup = function(){

    this.backup = '';
    this.mysql = require('mysql'),

    this.init = function(){
        this.connection = this.mysql.createConnection({
            user: 'root',
            password: 'root',
            database: 'test'
        });
    }

    this.query = function(sql, callback) {
        this.connection.query(sql, function (error, results, fields) {
            if (error) {
                throw error;
            }
            if (results.length  > 0) {
                callback(results);
            }
        });
    }

    this.get_tables = function(callback){
        var me = this;
        me.query('SHOW TABLES',
            function(tables) {
                for (var table in tables){
                    me.query(
                        'SHOW CREATE TABLE ' + tables[table].Tables_in_test,
                        function(r){
                            for (var t in r) {
                                me.backup += "DROP TABLE " + r[t].Table + "\n\n";
                                me.backup += r[t]["Create Table"] + "\n\n";
                            }
                        }
                    )
                }
                me.save_backup();
            });
    }

    this.save_backup = function(){
        var fs = require('fs');
        fs.writeFile("./backup_test.txt", this.backup, function(err) {
            if(err) {
                console.log(err);
            } else {
                console.log("The file was saved!");
            }
        });
    }

};

var db = new mysql_backup;
db.init();
db.get_tables();
db.connection.destroy();

推荐答案

编写的代码甚至都没有保存到我的文件中.似乎有一些问题.不知道这是实际的代码还是某些内容丢失在复制粘贴中.但是,根据您所拥有的:

The code as written didn't even get to a file saving for me. There seem like a few issues. Not sure if this is the actual code or some things got lost in the copy paste. However, based on what you've got:

一个很大的问题是,您永远不会使用connection.connect()连接到代码中的数据库.

A big one is that you never connect to the database in your code with connection.connect().

连接后要运行的代码应位于connection.connect()回调内部.例如

The code you want to run once connected should be inside the connection.connect() callback. e.g.

connection.connect(function (err, empty) {
    if (err)
        throw new Error ('Panic');

    // if no error, we are off to the races...
}

但是,即使您快速重构代码以将最后几行包装在该get连接回调中,您仍然会遇到问题,因为您在进行各种SQL调用之前就破坏了连接,因此您将需要将代码移到某种最终回调中.

However, even if you quickly refactor your code to wrap your last lines inside of that get connection callback, you'll still have problems, because you are destroying the connection before the various SQL calls are getting made, so you will want to move the code into some sort of final callback.

即使这样做,您仍然会有一个空文件,因为您是从"SHOW TABLES"回调中调用save_backup,而不是在通过内部回调实际填充了CREATE TABLE语句之后填充它并填充备份属性.

Even after you do that, you'll still have an empty file, because you're calling save_backup from your 'SHOW TABLES' callback rather than after you have actually populated it via the inner callback where you get the CREATE TABLE statement and populate the backup property.

这是对代码的最少重写,可以完成您的预期目标.要注意的重要事项是计数器",它管理何时写入文件和关闭连接.如果是我的,我会进行其他更改,包括:

This is the minimal rewriting of your code which will do what you are intending. An important thing to note is the "counter" which manages when to write the file and close the connection. I would make other changes if it were mine, including:

  • 使用自我"代替我"
  • 使用数字for循环而不是for(... in ...)语法
  • 我自己的回调属于(err,stuff)的节点约定
  • 一个更重大的变化是,我将使用Promise重写此代码,因为这样做可以使您深深地嵌套在深层的回调中,从而使您免于痛苦.我个人很喜欢Q库,但是这里有几种选择.

希望这会有所帮助.

var mysql_backup = function(){
    this.backup = '';
    this.mysql = require('mysql');

    this.init = function(){
        this.connection = this.mysql.createConnection({
            user     : 'root',
            password : 'root',
            database : 'test'
        });

    };

    this.query = function(sql, callback) {
        this.connection.query(sql, function (error, results, fields) {
            if (error) {
                throw error;
            }
            if (results.length  > 0) {
                callback(results);
            }
        });
    };

    this.get_tables = function(callback){
        var counter = 0;
        var me = this;
        this.query('SHOW TABLES',
            function(tables) {
                for (table in tables){
                    counter++;
                    me.query(
                        'SHOW CREATE TABLE ' + tables[table].Tables_in_mvc,
                        function(r){
                            for (t in r) {
                                me.backup += "DROP TABLE " + r[t].Table + "\n\n";
                                me.backup += r[t]["Create Table"] + "\n\n";
                            }
                            counter--;
                            if (counter === 0){
                                me.save_backup();
                                me.connection.destroy();

                            }
                        }
                    )
                }
            });
    };

    this.save_backup = function(){
        var fs = require('fs');
        fs.writeFile("./backup_test.txt", this.backup, function(err) {
            if(err) {
                console.log(err);
            } else {
                console.log("The file was saved!");
            }
        });
    }

};

var db = new mysql_backup;
db.init();
db.connection.connect(function (err){
    if (err) console.log(err);
    db.get_tables(function(x){;});

});

更新:如果您很好奇,这是一个使用Promise进行了广泛评论的实现.请注意,由于没有说明Q承诺库功能的注释,它比原始版本要短一些,并且还提供了更全面的错误处理.

Update: If you are curious, here is a heavily-commented implementation using promises. Note that without the comments explaining the Q promise library functions, it is somewhat shorter than the original version and also offers more comprehensive error handling.

var MysqlBackup = function(connectionInfo, filename){

    var Q = require('q');
    var self = this;
    this.backup = '';
    // my personal preference is to simply require() inline if I am only
    // going to use something a single time. I am certain some will find
    // this a terrible practice
    this.connection = require('mysql').createConnection(connectionInfo);

    function getTables(){
        //  return a promise from invoking the node-style 'query' method
        //  of self.connection with parameter 'SHOW TABLES'.
        return Q.ninvoke(self.connection,'query', 'SHOW TABLES');
    };

    function doTableEntries(theResults){

        // note that because promises only pass a single parameter around,
        // if the 'denodeify-ed' callback has more than two parameters (the
        // first being the err param), the parameters will be stuffed into
        // an array. In this case, the content of the 'fields' param of the
        // mysql callback is in theResults[1]

        var tables = theResults[0];
        // create an array of promises resulting from another Q.ninvoke()
        // query call, chained to .then(). Note that then() expects a function,
        // so recordEntry() in fact builds and returns a new one-off function
        // for actually recording the entry (see recordEntry() impl. below)

        var tableDefinitionGetters = [];
        for (var i = 0; i < tables.length ; i++){
            //  I noticed in your original code that your Tables_in_[] did not
            //  match your connection details ('mvc' vs 'test'), but the below
            //  should work and is a more generalized solution
            var tableName = tables[i]['Tables_in_'+connectionInfo.database];

            tableDefinitionGetters.push(Q.ninvoke(self.connection, 'query', 'SHOW CREATE TABLE ' + tableName)
                                        .then(recordEntry(tableName)) );
        }

        // now that you have an array of promises, you can use Q.allSettled
        // to return a promise which will be settled (resolved or rejected)
        // when all of the promises in the array are settled. Q.all is similar,
        // but its promise will be rejected (immediately) if any promise in the
        // array is rejected. I tend to use allSettled() in most cases.

        return Q.allSettled(tableDefinitionGetters);
    };

    function recordEntry (tableName){
        return function(createTableQryResult){
            self.backup += "DROP TABLE " + tableName + "\n\n";
            self.backup += createTableQryResult[0][0]["Create Table"] + "\n\n";
        };
    };

    function saveFile(){
        // Q.denodeify return a promise-enabled version of a node-style function
        // the below is probably excessively terse with its immediate invocation
        return (Q.denodeify(require('fs').writeFile))(filename, self.backup);
    }

    // with the above all done, now you can actually make the magic happen,
    // starting with the promise-return Q.ninvoke to connect to the DB
    // note that the successive .then()s will be executed iff (if and only
    // if) the preceding item resolves successfully, .catch() will get
    // executed in the event of any upstream error, and finally() will
    // get executed no matter what.

    Q.ninvoke(this.connection, 'connect')
    .then(getTables)
    .then(doTableEntries)
    .then(saveFile)
    .then( function() {console.log('Success'); } )
    .catch( function(err) {console.log('Something went awry', err); } )
    .finally( function() {self.connection.destroy(); } );
};

var myConnection = {
    host     : '127.0.0.1',
    user     : 'root',
    password : 'root',
    database : 'test'
};

// I have left this as constructor-based calling approach, but the
// constructor just does it all so I just ignore the return value

new MysqlBackup(myConnection,'./backup_test.txt');

这篇关于NodeJS MySQL转储的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆