Search code examples
mysqlnode.jsknex.js

How to debug knex.js? Without having to pollute my db


does anyone know anything about debugging with knexjs and mysql? I'm trying to do a lot of things and test out stuff and I keep polluting my test database with random data. ideally, I'd just like to do things and see what the output query would be instead of running it against the actual database to see if it actually worked.

I can't find anything too helpful in their docs. they mention passing {debug: true} as one of the options in your initialize settings but it doesn't really explain what it does.

I am a junior developer, so maybe some of this is not meant to be understood by juniors but at the end of the day Is just not clear at all what steps I should take to be able to just see what queries would have been ran instead of running the real queries and polluting my db.

const result = await db().transaction(trx =>
    trx.insert(mapToSnakeCase(address), 'id').into('addresses')
      .then(addressId =>
        trx.insert({ addresses_id: addressId, display_name: displayName }, 'id')
          .into('chains')).toString();

Solution

  • You can build a knex query, but until you attach a .then() or awiat() (or run . asCallback((error,cb)=>{})), the query is just an object.

    So you could do

    let localVar = 8
    let query = knex('table-a').select().where('id', localVar)
    console.log(query.toString())
    // outputs a string 'select * from table-a where id = 8'
    

    This does not hit the database, and is synchronous. Make as many of these as you want!

    As soon as you do await query or query.then(rows => {}) or query.asCallback( (err,rows)=>{} ) you are awaiting the db results, starting the promise chain or defining the callback. That is when the database is hit.

    Turning on debug: true when initializing just writes the results of query.toSQL() to the console as they run against the actual DB. Sometimes an app might make a lot of queries and if one goes wrong this is a way to see why a DB call failed (but is VERY verbose so typically is not on all the time).

    In our app's tests, we do actually test against the database because unit testing this type of stuff is a mess. We use knex's migrations on a test database that is brought down and up every time the tests run. So it always starts clean (or with known seed data), and if a test fails the DB is in the same state to be manually inspected. While we create a lot of test data in a testing run, it's cleaned up before the next test.