knex: Documentation for returning functionality in MySQL is not clear enough in all cases

Environment

Knex version: 0.16.5 Database + version: MySQL 5.7

Bug

db.insert({data}, 'an_id').into('foobar')

That sort of statement is giving returning() is not supported by mysql and will not have any effect. Note that this statement is not using returning() but is relying on Knex’s internal version of it for MySQL.

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Comments: 30 (10 by maintainers)

Most upvoted comments

The documentation promotes this syntax:

image

Tip: If you’re mutating a record in the database, and you have the input data, just return that directly upon a successful mutation.

ExpressJS example:

app.post('/api/v1/users', async (req, res, next) => {
  const someBookData = req.body

  try {
    const arrayOfPrimaryKeysSuccessfullyInserted = await knex('books').insert(someBookData) // So this could be like [40222] where 40222 is the PK value in your users table
    res.status(200).send({
      id: arrayOfPrimaryKeysSuccessfullyInserted[0], // [40222][0] = 40222
      ...someBookData // the original book data
    })
  } catch(err) {
    next(err)
  }
})

I think this is correct, but someone feel free to correct me.

@rijkvanzanten probably the easiest and fastest way for you is to write knex plugin, which implements crossdb insert that works in your case.

Something like:

const Knex = require('knex');
Knex.QueryBuilder.extend('insertAndReturnId', function(value) {
  const builder = this.insert(value);
  if (this.client.driverName === 'pg' || this.client.driverName === 'oracledb') {
    builder.returning('id');
  }
  return builder;
});

const id= await knex('accounts').insertAndeturnId({});

Wow.

  1. Yes, the documentation is MySQL specific. I highlighted the dropdown that indicates it is so.
  2. It shouldn’t matter what the documentation behind the “returning method” says because this documentation is clearly indicating that Knex will do the right thing for MySQL when given this syntax.

@jsumners Why are you passing second param to insert? It is literally a returning argument.