Insert with custom id

Hi there,

I would like to create an entity with a specific id. I have a table where i delete everything and i would like to reset the auto increment to zero of id. Is this possible? I am using bookshelf connection to sqlite.

Thanks in advance,
Nik

1 Like

We don’t specifically have a Strapi process for that but you could use the bookshelf custom query: https://strapi.io/documentation/v3.x/concepts/queries.html#bookshelf

Or you can directly use knex and run a raw SQL query like strapi.connections.default.raw('Some SQL Query Here')

1 Like

Thanks for the quick response.

I managed to use bookshelf to make the insertion, still i had to filter out any extra wrong attributes from the input, is there a function for it?

I share my code for everyone else:
strapi.query('TABLENAME').model.forge({id, ...other fields}).save(null, {method: 'insert'});

I don’t believe we have one but I’ll poke @alexandrebodin to see if there is a function I’m unaware of

@nikatlas : Thank you for the code! Exactly what I was looking for.

Do you know (or anyone else reading this) what should I add to be able to work with relations? Example:

{
ā€œidā€: 1337,
"name: ā€œleetā€,
"tags: [1,3]
}

I guess I need to add somewhere {withRelated: [ā€˜tags’]}, but can’t figure it out where.

@SlaaAvi I managed to insert an entry with relations similar to yours without passing any extra stuff.

tags: [1 ,3] supposed tags is a collection field and 1,3 are targetids

Note: The array must be of array form in the time of insertion. Watch out whether its stringified or something…

I created this function just for this purpose. It worked for me…

const filterModel = (model, item) => {
  let res = {};
  // console.log(model._attributes)
  for(var i in model._attributes)
    if(item[i]){
      if(model._attributes[i].type) {
        res[i] = item[i];
      } else if (model._attributes[i].collection) {
        res[i] = JSON.parse(item[i]);
      } else if (model._attributes[i].model) {
        res[i] = parseInt(item[i]);
      }
    }
  return res;
}

Thanks for the quick reply.

I tried to implement the code in my controller (/post/controllers/post.js), but can’t make it work.

I don’t know what model and item should I pass in the filterModel function.

So at the moment this is the working controller with your first code.

const { parseMultipartData, sanitizeEntity } = require("strapi-utils");

module.exports = {
  async create(ctx) {
    let entity;
    if (ctx.is("multipart")) {
      // const { data, files } = parseMultipartData(ctx);
      // entity = await strapi.services.post.create(data, { files });
      return "multipart disabled";
    } else {
      // entity = await strapi.services.post.create(ctx.request.body);
      entity = await strapi
        .query("post")
        .model.forge(ctx.request.body)
        .save(null, { method: "insert" });
    }
    return sanitizeEntity(entity, { model: strapi.models.post });
  },
};

Works when I make new post api req { ā€œidā€: 1337, ā€œnameā€: ā€œleetā€ }, but not working when I include "tags: [1,3].

I’ve tried couple of ways to implement your last code (like this one below), but can’t make it work. (still learning js)

const { parseMultipartData, sanitizeEntity } = require("strapi-utils");

module.exports = {
  async create(ctx) {
    const filterModel = (model, item) => {
      let res = {};
      console.log(model._attributes);
      for (var i in model._attributes)
        if (item[i]) {
          if (model._attributes[i].type) {
            res[i] = item[i];
          } else if (model._attributes[i].collection) {
            res[i] = JSON.parse(item[i]);
          } else if (model._attributes[i].model) {
            res[i] = parseInt(item[i]);
          }
        }
      console.log(res);
      return res;
    };

    let entity;
    if (ctx.is("multipart")) {
      // const { data, files } = parseMultipartData(ctx);
      // entity = await strapi.services.post.create(data, { files });
      return "multipart disabled";
    } else {
      // entity = await strapi.services.post.create(ctx.request.body);
      entity = await strapi
        .query("post")
        .model.forge(filterModel(strapi.models.tag, ctx.request.body.tags))
        .save(null, { method: "insert" });
    }
    return sanitizeEntity(entity, { model: strapi.models.post });
  },
};

You should pass the whole Object as item

 {
ā€œidā€: 1337,
"name: ā€œleetā€,
"tags: [1,3]
}

And as model you need to pass the model this item is(in your case seems post).

...
.model.forge(filterModel(strapi.models.post, ctx.request.body))
...

Thanks. I tried as well to pass the model (post) with the whole Object (ctx.request.body) … but still it’s not working.

I think something in the filterModel function is happening, because when I console.log the return res is showing only ā€œnameā€ property left. ā€œidā€ and ā€œtagsā€ are gone.

Sorry for hijacking your thread

Console log your strapi.models.post._attributes to see what fields are there.
The function simply keeps only these attributes.