Search code examples
javascriptnode.jsexpressappfog

Update and or fix the schema of an AppFog Database


I created an app in NodeJS using ExpressJS, I hosted my app on AppFog and it works, however, I made a few update on my local version, now I'd like to update my App on AppFog but I got a problem, because I updated my models in local and now, I can't update my AppFog database...

What am I suppose to do? Delete the App and Update again? I'll lost all my data in my database...

Logs:

Error: ER_BAD_FIELD_ERROR: Unknown column 'tags' in 'field list'

Solution

  • First export the database to keep a backup just in case this does not go as expected.

    1. af apps to get the db service name for the app
    2. af export-service [service-name] to get a download url of a backup

    Next tunnel the service to your local box. Note this can be a little finicky so give it a few tries if needed.

    1. af tunnel [service-name]
    2. Pick the connection option you need. Option "none" will output credentials that can be used with your favorite db tool. Setup a db connection to localhost port 10000 and use the dbname, username, and password provided. Option "mysql" will automatically connect to the db with the mysql cli. Closing the terminal window or exiting af tunnel command will drop the local tunnel so keep it running while making changes. More on af tunnel here.
    1: none <- this will let you connect using sequel pro
    2: mysql <- to make manual tweeks
    3: mysqldump
    

    Finally repair the database structure as needed to get your app working and then update the app.


    Additionally, in the future you might what to use an ORM like Sequelize which has non-destructive db migrations that can be run when the app starts up after an af update

    Somewhere early in your startup file:

    // Sudo code. see af online docs on how to get the bound service creds
    if (process.env.NODE_ENV == "production") {
      var sequelize = new Sequelize(appfog.dbname, appfog.username, appfog.password, ...)
    
      var migratorOptions = { path: process.cwd() + '/migrations' };
      var migrator        = sequelize.getMigrator(migratorOptions);
      migrator.migrate();
    }