How do I specify a single file to be seed only
Asked Answered
G

6

15

I am using knex for seeding and I have a folder called development where I have all the seeds files.

What I would want is: How to seed single file.

The command I am using is: knex seed:run --env=development But this command is to seed all the files and I get duplicate rows on db.

Suppose I have created seed files yesterday, and I seed them, today I want to add another seed file, which I only want to seed this file, not the files from yesterday.

An example from Laravel is: php artisan db:seed --class=ProductTableSeeder

Thanks

Gonsalez answered 28/4, 2015 at 12:4 Comment(0)
S
24

For those of you checking this in 2019+

According to the knex documentation

To run a specific seed file, execute:

$ knex seed:run --specific=seed-filename.js
Simon answered 16/10, 2019 at 1:37 Comment(3)
Hey there. Thanks for the update but it still doesn't work. It's like --specific isn't even there and all my seeds run :( Any idea why?Watercolor
I'm not sure without seeing more of the code, but is the seeds directory path within your knexfile.js set up to point to your seed folder?Simon
@Watercolor I also had your issue. For me, using the -- separator ended up fixing it (posted as an answer below). Does it solve your issue, too?Sauceda
O
7

Just move your scripts to another folder except the desired script, run the seed and copy the scripts back.

The seed API only has two commands, make and run. This is from the docs.

runknex.seed.run([config])

Runs all seed files for the current environment.

So all scripts will be executed on each run

Owens answered 28/4, 2015 at 12:24 Comment(7)
If I do this way, than I should do the seed for each specific folder if I want to execute the seed files in another machine ??Gonsalez
You can also write a batch to rename the other scripts so knex ignore them on the seeds execution as an alternative but if you leave them in the folder they will get executed. Also they will run in alphabetical order so you must be carefull with the names of the scripts.Owens
I use numbers as prefix like for ex : 01, 02 so i dont have the problem with the ordering, regarding the batch i dont understand it how u really mean that?Gonsalez
Does knex provides any option like this: knex seed:run --file=nameOfFileGonsalez
Not that I know of. What i mean is that if you rename seed_table1.js to seed_table1.ttt it will not be executed. The same way if you leave your target script in the folder alone. Those are your options. The source code says that everything ending with '.co', '.coffee', '.iced', '.js', '.litcoffee', '.ls' will be added tho the stack and executed.Owens
Waiting for someone else give an answer, as for now I cant accept your answer as it does not fully fulfill my needs :s Anyhow thanks for ur answer, let see if there is any better way..Gonsalez
Ok I understand ;). If you want to know what are your options you should go to the npm folder and look for npm\node_modules\knex\lib\seed\index.js file. In line 42 is Seeder.prototype._listAll method. This is the one with the task of finding the target files to seed.Owens
I
2

Don't work: knex seed:run --specific=seed-filename.js

  1. create in DB knex_seed_lock table
  2. Add this to seed file:

const file_name = path.basename(__filename)
  const seedIsExist = await knex('knex_seeds_lock').where({ file_name }).first()

  if (seedIsExist) {
    return
  }
  1. And add this to the end of the file:

await knex('knex_seeds_lock').insert({ file_name })

As a result, in the database you will get all the seed ​​that you already ran earlier

Ionogen answered 16/4, 2020 at 19:10 Comment(0)
E
1

Personally I just wrap my promise in exports.up/down in an if (boolean) {...} and switch the ones to false that I don't want to run.

Ellingson answered 27/10, 2015 at 9:56 Comment(0)
C
1

The solution from Artem works fine: You just need to create table: knex_seeds_lock

The code that i used is here:

`
    const path = require('path')
    exports.seed = async (knex) => {
        try {
            const file_name = path.basename(__filename)
            const seedIsExist = await knex('knex_seeds_lock').where({ file_name }).first()
            if (seedIsExist) {
                return
            } else {
                await knex('users_types').del();
                await knex('knex_seeds_lock').insert({ file_name })
                await knex('users_types').insert([
                    {name: 'client'},
                    {name: 'driver'},
                    {name: 'admin'}
                ]);
                return;
             }
         } catch (err) {
             console.log("ERROR SEEDING")
             console.log(err);
         }
    }`
Ciliolate answered 8/7, 2020 at 0:8 Comment(0)
S
0

@Madison_Lai's answer is correct, but similar to one comment on that answer my --specific flag was also being ignored.

TLDR: Adding the -- separator solved my issue.

npm run knex seed:run -- --specific=seed-filename.js

Details:

In my case, the knex script in my package.json included a passed argument, which ended up causing ordering issues when I tried to pass additional arguments via CLI.

In package.json

"scripts": {
  "knex": "./path/to/knex --knexfile=./path/to/knexfile.js"
}

In CLI,

npm run knex seed:run --specific=seed-filename.js

was getting parsed as below, completely losing the --specific argument

./path/to/knex --knexfile=./path/to/knexfile.js "seed:run"

Prefixing -- before passing the additional argument (as recommended here) solved the issue for me

npm run knex seed:run -- --specific=seed-filename.js
Sauceda answered 24/8, 2022 at 3:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.