Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript PersistenceJS:使用migrate()更新现有数据库_Javascript_Html_Persistence - Fatal编程技术网

Javascript PersistenceJS:使用migrate()更新现有数据库

Javascript PersistenceJS:使用migrate()更新现有数据库,javascript,html,persistence,Javascript,Html,Persistence,我目前正在尝试使用PersistenceJS的迁移插件对现有数据库进行更改。我可以在数据库中添加/编辑/删除项目,但是 如何向现有(!)表中添加列 如何更改现有(!)列的类型,例如从“文本”更改为“整数” 这些更改应保留当前的现有数据。 遗憾的是,文档有点少,也许你能帮忙 以下是当前的工作设置: 有点作用的迁移代码: 结果… 调用migrate()只会登录到“migration init”,不会调用完整的处理程序,也不会创建“due”列 在调用migrate()之前不调用schemaAsyn

我目前正在尝试使用PersistenceJS的迁移插件对现有数据库进行更改。我可以在数据库中添加/编辑/删除项目,但是

  • 如何向现有(!)表中添加列
  • 如何更改现有(!)列的类型,例如从“文本”更改为“整数”

  • 这些更改应保留当前的现有数据。

遗憾的是,文档有点少,也许你能帮忙

以下是当前的工作设置:

有点作用的迁移代码:

结果…
  • 调用migrate()只会登录到“migration init”,不会调用完整的处理程序,也不会创建“due”列
  • 在调用migrate()之前不调用schemaAsync(),正如Zef Hemel自己在中提出的那样,会产生与1相同的结果
  • 将第一行更改为
    persistence.store.websql.config(persistence,'newdatabase','testingmigration',5*1024*1024),不调用schemaAsync()并且只调用migrate()将成功地记录“migration complete!”——但是它在一个新的、完全空的数据库“newdatabase”中这样做,这当然不会保留任何现有数据
  • 总结 有一个数据库是使用
    persistence.store.websql.config(…)
    persistence.define('Todo',…)
    persistence.schemaAsync()
    创建的

    我现在想保留数据库中已经存在的所有数据,但我想

    • 将列
      优先级
      的类型从“整数”更改为“文本”
    • 将类型为“日期”的列
      due
      添加到所有现有TODO
    如果你能把我推向正确的方向,我将不胜感激


    谢谢

    我终于让它工作了。我的初始需求中有许多问题,我想指出以供将来参考。请看第一个迁移定义:

    persistence.defineMigration(1, {
        up: function() {
            this.createTable('Todo', function(t){
            ...
    

    毫不奇怪,
    createTable
    将执行以下操作:它将执行SQL语句
    'createtablettodo…
    ,如果已经有一个名为
    Todo
    的表,该语句将自动失败并停止迁移。这就是为什么它使用新数据库,而不是现有数据库。请记住:我已经有了一个实时数据库,其中的表“Todo”需要更新。如果您是从新开始的(即,您没有使用过
    schemaAsync
    ),那么
    createTable
    工作正常。由于迁移插件不提供
    createTableIfNotExists
    方法,因此我需要使用
    executeSql
    ,如下所示:

    persistence.defineMigration(1, {
        up: function() {
            this.executeSql('CREATE TABLE IF NOT EXISTS Todo (id VARCHAR(32) PRIMARY KEY, task TEXT, priority INT, done BOOL)');
            ...
    

    现在,从架构版本0到1的迁移成功了,到版本2的迁移也成功了

    随着迁移到版本3,
    priority
    列的类型需要从
    int
    更改为
    text
    。这通常使用
    ALTER COLUMN
    SQL命令来完成,而Web SQL/SQLite不支持该命令。请参见

    使用SQLite更改列需要4步解决方法:

    persistence.defineMigration(3, {
        up: function() {
            // rename current table
            this.executeSql('ALTER TABLE Todo RENAME TO OldTodo');
            // create new table with required columns and column types
            this.executeSql('CREATE TABLE Todo (id VARCHAR(32) PRIMARY KEY, task TEXT, priority TEXT, done BOOL)');
            // copy contents from old table to new table
            this.executeSql('INSERT INTO Todo(id, task, priority, done) SELECT id, task, priority, done FROM OldTodo');
            // delete old table
            this.executeSql('DROP TABLE OldTodo');
        },
        ...
    

    当然,更改列类型后,“Todo”的实体定义也应更改:

    var Todo = persistence.define('Todo', {
        task: 'TEXT',
        priority: 'TEXT', // was 'INT'
        due: 'DATE',
        done: 'BOOL'
    });
    

    最后,完整的来源:
    这是一个很好的解释,谢谢!但我想我知道一个更容易实现的方法

    我和你一样也遇到了同样的麻烦:我得到了一组用
    persistence.define
    描述的模式,并用
    persistence.schemaAsync
    创建

    这就是我的特殊情况:

        // This is my mixin for all schemas    
        var Versioned = persistence.defineMixin('Versioned', {
          serverId: "TEXT",
          intVersion: "INT",
          dtSynced: "DATE",
          dtCreatedAt: "DATE",
          dtUpdatedAt: "DATE",
          delete: "BOOL",
          update: "BOOL",
          add: "BOOL",
          isReadOnly: "BOOL"
        });
    
        // This is one of the schemas I need to update with a new field.        
        var Person = persistence.define('Person', {
          fullName: "TEXT",
          rate: "INT"
        });
    
        //... More schema definitions
    
        // Setup mixin        
        Person.is(Versioned);
    
        // Sync schemas
        persistence.schemaSync();
    
    嗯。没什么特别的。现在,在我的应用程序投入生产几个月后,我想在
    个人
    模式中添加一个新字段
    isEmployed

    根据文档,我应该将所有模式定义重写到迁移中,并停止使用
    persistence.schemaAsync()
    。但我不想重写我所有的定义。相反,我在PersistenceJS init代码后面定义了一个新的迁移:

        // Init ORM
        persistence.store.websql.config(
          persistence,
          'Sarafan',
          '0.0.2',                
          'Sarafan.app database', 
          100 * 1024 * 1024,      
          0                        
       );
    
        // Define Migrations
        persistence.defineMigration(1, {
          up: function () {
            this.addColumn('Person', 'isEmployed', 'BOOL');
          }
        });
    
        // ... describing isVersioned mixin
    
    
        // Updated schema definition with a new field 'isEmployed'
        var Person = persistence.define('Person', {
          fullName: "TEXT",
          rate: "INT",
          isEmployed: "BOOL"
        });
    
        //... More schema definitions
    
        // Setup mixin        
        Person.is(Versioned);
    
        // Apply the migration right away from the schemaSync call.
        persistence.schemaSync(function (tx) {
          persistence.migrations.init(function () {
          persistence.migrate(function(){
            // Optional callback to be executed after initialization
            });
          });
        });
    
    就这样!我测试这种方法只是为了向模式中添加新字段

    让我知道它是否对你有效

    persistence.store.websql.config(persistence, 'tododatabase', 'todos are fun', 5*1024*1024);
    
    // persistence.debug = true;
    
    //v0 + v1
    // var Todo = persistence.define('Todo', {
    //  task: 'TEXT',
    //  priority: 'INT',
    //  done: 'BOOL'
    // });
    
    //v2
    // var Todo = persistence.define('Todo', {
    //  task: 'TEXT',
    //  priority: 'INT',
    //  due: 'DATE',
    //  done: 'BOOL'
    // });
    
    //v3
    var Todo = persistence.define('Todo', {
        task: 'TEXT',
        priority: 'TEXT',
        due: 'DATE',
        done: 'BOOL'
    });
    
    
    persistence.defineMigration(1, {
        up: function() {
            this.executeSql('CREATE TABLE IF NOT EXISTS Todo (id VARCHAR(32) PRIMARY KEY, task TEXT, priority INT, done BOOL)');
        },
        down: function() {
            this.dropTable('Todo');
        }
    });
    
    persistence.defineMigration(2, {
        up: function() {
            this.addColumn('Todo', 'due', 'DATE');
        },
        down: function() {
            this.removeColumn('Todo', 'due');
        }
    });
    
    persistence.defineMigration(3, {
        up: function() {
            // rename current table
            this.executeSql('ALTER TABLE Todo RENAME TO OldTodo');
            // create new table with required columns
            this.executeSql('CREATE TABLE Todo (id VARCHAR(32) PRIMARY KEY, task TEXT, priority TEXT, due DATE, done BOOL)');
            // copy contents from old table to new table
            this.executeSql('INSERT INTO Todo(id, task, priority, due, done) SELECT id, task, priority, due, done FROM OldTodo');
            // delete current table
            this.executeSql('DROP TABLE OldTodo');
        },
        down: function() {
            this.executeSql('ALTER TABLE Todo RENAME TO OldTodo');
            this.executeSql('CREATE TABLE Todo (id VARCHAR(32) PRIMARY KEY, task TEXT, priority INT, due DATE, done BOOL)');
            this.executeSql('INSERT INTO Todo(id, task, priority, due, done) SELECT id, task, priority, due, done FROM OldTodo');
            this.executeSql('DROP TABLE OldTodo');
        }
    });
    
    
    function migrate( callback ){
        console.log('migrating...');
        persistence.migrations.init( function(){
            console.log('migration init');
            persistence.migrate( function(){
                console.debug('migration complete!');
                callback();
            } );
        });
    };
    
    migrate( onMigrationComplete );
    
    function onMigrationComplete(){
        // database is ready. do amazing things...
    };
    
        // This is my mixin for all schemas    
        var Versioned = persistence.defineMixin('Versioned', {
          serverId: "TEXT",
          intVersion: "INT",
          dtSynced: "DATE",
          dtCreatedAt: "DATE",
          dtUpdatedAt: "DATE",
          delete: "BOOL",
          update: "BOOL",
          add: "BOOL",
          isReadOnly: "BOOL"
        });
    
        // This is one of the schemas I need to update with a new field.        
        var Person = persistence.define('Person', {
          fullName: "TEXT",
          rate: "INT"
        });
    
        //... More schema definitions
    
        // Setup mixin        
        Person.is(Versioned);
    
        // Sync schemas
        persistence.schemaSync();
    
        // Init ORM
        persistence.store.websql.config(
          persistence,
          'Sarafan',
          '0.0.2',                
          'Sarafan.app database', 
          100 * 1024 * 1024,      
          0                        
       );
    
        // Define Migrations
        persistence.defineMigration(1, {
          up: function () {
            this.addColumn('Person', 'isEmployed', 'BOOL');
          }
        });
    
        // ... describing isVersioned mixin
    
    
        // Updated schema definition with a new field 'isEmployed'
        var Person = persistence.define('Person', {
          fullName: "TEXT",
          rate: "INT",
          isEmployed: "BOOL"
        });
    
        //... More schema definitions
    
        // Setup mixin        
        Person.is(Versioned);
    
        // Apply the migration right away from the schemaSync call.
        persistence.schemaSync(function (tx) {
          persistence.migrations.init(function () {
          persistence.migrate(function(){
            // Optional callback to be executed after initialization
            });
          });
        });