How do I specify a single file to be seed only - javascript

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

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

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

Don't work: knex seed:run --specific=seed-filename.js
create in DB knex_seed_lock table
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
}
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

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.

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);
}
}`

#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

Related

Requiring files in electron without babel

I'm trying to convert a web application into an electron app. I have multiple functions, in different files that I've imported into my main.js using a transpiler.
However, whenever I try do that in my electron app, I run into an issue with a module I'm using to move away from using php to access my database. Instead I'm using the mysql module on npm.
I want to save this function in its own file, and then require it in main.js. When I try to transpile it with babel, I get an error about Net.Connection not working (or something along those lines). As I understand it, this is because of how Node works. I'm happy to work around this, but I'm hoping there's a way to save this function in another file, and import it without having to use babel.
function loadColourFilter(){
var mysql = require('mysql');
let query_result;
var connection = mysql.createConnection({
host : 'xxxxxxxxxxxx',
user : 'xxxxxxxxxxxx',
password : 'xxxxxxxxxxxx',
database : 'xxxxxxxxxxxx'
});
connection.connect();
let query = "xxxxxxxxxxxxxxxx";
connection.query(query, function (error, results, fields) {
});
connection.end();
return (query_result);
}
EDIT: I've removed some parts of the function to keep credentials safe and whatnot. I'm fairly certain their absence won't change anything when trying to solve this.
EDIT:
My project directory is essentially
src
--- js
--- --- main.js
--- functionFile.js // This would be where my loadColourFilter function above would be saved
--- node_modules
--- --- ...
--- index.html // js/main.js is referenced in a script tag here.
--- main.js // Where the electron window is created.
--- package.json
There should be 2 js contexts, one running in the electron app and one running in node. You won't be able to require you scripts directly from your directory if you are in the electron context (which is like a browser js context).
I'm just assuming this is the case since we don't get a lot of information for your problem, and the other answer should have resolved your problem.
Try to include your js file in your index.html and see what's up.
Edit: Since it's a Transpiling error with babel, babel is probably transpiling for node when it should transpile for the browser.
You can easily make a simple local module using NodeJS by creating a source file and then adding a module.exports assignment to export some functionality/variables/etc from the file. In your case something like a file named colourFilter.js with the contents:
function load(){
var mysql = require('mysql');
let query_result;
var connection = mysql.createConnection({
host : 'xxxxxxxxxxxx',
user : 'xxxxxxxxxxxx',
password : 'xxxxxxxxxxxx',
database : 'xxxxxxxxxxxx'
});
connection.connect();
let query = "xxxxxxxxxxxxxxxx";
connection.query(query, function (error, results, fields) {
});
connection.end();
return (query_result);
}
module.exports = load
And then in your code where you'd like to use it include it by doing something like:
loadColourFilter = require('colourFilter.js')
And use the function like
let result = loadColourFilter()
This is a simple way to split up your code into multiple files/classes/modules but still keep one main file/class/module as the important one which is the public-facing portion or entry point. And of course you don't have to use the names I've used above :P
If you would like to make an object-style module you can instead export an object like
module.exports = {
load
}
Or
module.exports = {
load: loadFunctionNameInThisFile
}
And then use it like
const colourFilter = require('colourFilter.js')
let result = colourFilter.load()

Getting test results when creating a Karma server programmatically

I am trying to run multiple Karma test files in parallel from inside a Node script and get to know which tests are passing or failing. Right now what I have is this:
const exec = require("child_process").exec;
exec("karma start " + filename, (error, stdout, stderr) => {
// handle errors and test results...
});
The code above works well, and I can get the information on tests passed or failed from stdout. However, it requires having installed Karma and all of the associated dependencies (reporters, browser launchers, etc.) globally. I am looking for a solution that doesn't require me to install all dependencies globally.
My first thought was this:
const karma = require("karma");
const server = new karma.Server(config, () => {
// some logic
});
However, when trying this other approach, I have been unable to gather the test results programmatically.
When using new karma.Server(), is there any way in which I could know which tests have passed or failed (and, ideally, a stack trace of the error)? Alternatively, is there any other way in which I can execute my tests and get the desired information programmatically without the need to install dependencies globally?
Actually, changing the exec line to this seems to do the trick:
exec("node node_modules/karma/bin/karma start " + filename, (error, stdout, stderr) => {
It turns out I'd only need to run the locally installed version of Karma instead of the global one. :-)

Run function in script from command line (Node JS)

I'm writing a web app in Node. If I've got some JS file db.js with a function init in it how could I call that function from the command line?
No comment on why you want to do this, or what might be a more standard practice: here is a solution to your question.... Keep in mind that the type of quotes required by your command line may vary.
In your db.js, export the init function. There are many ways, but for example:
module.exports.init = function () {
console.log('hi');
};
Then call it like this, assuming your db.js is in the same directory as your command prompt:
node -e 'require("./db").init()'
If your db.js were a module db.mjs, use a dynamic import to load the module:
node -e 'import("./db.mjs").then( loadedModule => loadedModule.init() )'
To other readers, the OP's init function could have been called anything, it is not important, it is just the specific name used in the question.
Update 2020 - CLI
As #mix3d pointed out you can just run a command where file.js is your file and someFunction is your function optionally followed by parameters separated with spaces
npx run-func file.js someFunction "just some parameter"
That's it.
file.js called in the example above
const someFunction = (param) => console.log('Welcome, your param is', param)
// exporting is crucial
module.exports = { someFunction }
More detailed description
Run directly from CLI (global)
Install
npm i -g run-func
Usage i.e. run function "init", it must be exported, see the bottom
run-func db.js init
or
Run from package.json script (local)
Install
npm i -S run-func
Setup
"scripts": {
"init": "run-func db.js init"
}
Usage
npm run init
Params
Any following arguments will be passed as function parameters init(param1, param2)
run-func db.js init param1 param2
Important
the function (in this example init) must be exported in the file containing it
module.exports = { init };
or ES6 export
export { init };
As per the other answers, add the following to someFile.js
module.exports.someFunction = function () {
console.log('hi');
};
You can then add the following to package.json
"scripts": {
"myScript": "node -e 'require(\"./someFile\").someFunction()'"
}
From the terminal, you can then call
npm run myScript
I find this a much easier way to remember the commands and use them
Try make-runnable.
In db.js, add require('make-runnable'); to the end.
Now you can do:
node db.js init
Any further args would get passed to the init method, in the form of a list or key-value pairs.
Sometimes you want to run a function via CLI, sometimes you want to require it from another module. Here's how to do both.
// file to run
const runMe = () => {}
if (require.main === module) {
runMe()
}
module.exports = runMe
This one is dirty but works :)
I will be calling main() function from my script. Previously I just put calls to main at the end of script. However I did add some other functions and exported them from script (to use functions in some other parts of code) - but I dont want to execute main() function every time I import other functions in other scripts.
So I did this,
in my script i removed call to main(), and instead at the end of script I put this check:
if (process.argv.includes('main')) {
main();
}
So when I want to call that function in CLI: node src/myScript.js main
simple way:
let's say you have db.js file in a helpers directory in project structure.
now go inside helpers directory and go to node console
helpers $ node
2) require db.js file
> var db = require("./db")
3) call your function (in your case its init())
> db.init()
hope this helps
Updated for 2022 - If you've switched to ES Modules, you can't use the require tricks, you'd need to use dynamic imports:
node -e 'import("./db.js").then(dbMod => dbMod.init());'
or with the --experimental-specifier-resolution=node flag:
node --experimental-specifier-resolution=node -e 'import("./db").then(dbMod => dbMod.init());'
If you turn db.js into a module you can require it from db_init.js and just: node db_init.js.
db.js:
module.exports = {
method1: function () { ... },
method2: function () { ... }
}
db_init.js:
var db = require('./db');
db.method1();
db.method2();
I do a IIFE, something like that:
(() => init())();
this code will be executed immediately and invoke the init function.
You can also run TypeScript with ts-node similar to #LeeGoddard answer.
In my case, I wanted to use app and init separately for testing purposes.
// app.ts
export const app = express();
export async function init(): Promise<void> {
// app init logic...
}
npx ts-node -e 'require("./src/app").init();'
npx ts-node -e 'import("./src/app").then(a => a.init());' // esmodule
maybe this method is not what you mean, but who knows it can help
index.js
const arg = process.argv.splice(2);
function printToCli(text){
console.log(text)
}
switch(arg[0]){
case "--run":
printToCli("how are you")
break;
default: console.log("use --run flag");
}
and run command node . --run
command line
probuss-MacBook-Air:fb_v8 probus$ node . --run
how are you
probuss-MacBook-Air:fb_v8 probus$
and you can add more arg[0] , arg[1], arg[2] ... and more
for node . --run -myarg1 -myarg2
If you want to include environment variables from your .env files, you can use env-cmd:
npx env-cmd node -e 'require("./db").init()'
If you want run a specific function in the file too, use run-func:
npx env-cmd npx run-func db.js init someArg
Or, to provide an argument for the accepted answer you'd have to do something like:
npx env-cmd node -e 'require("./db").init(someArg)'
Writing/updating an expression here is less explicit (so easier to miss when you're checking back, for example) than providing different arguments to the commands, so I recommend using env-cmd with run-func.
Note: I also usually add --experimental-modules on the end when necessary.
Inspired by https://github.com/DVLP/run-func/blob/master/index.js
I create https://github.com/JiangWeixian/esrua
if file index.ts
export const welcome = (msg: string) => {
console.log(`hello ${msg}`)
}
just run
esrua ./index.ts welcome -p world
will output hello world
If your file just contains your function, for example:
myFile.js:
function myMethod(someVariable) {
console.log(someVariable)
}
Calling it from the command line like this nothing will happen:
node myFile.js
But if you change your file:
myFile.js:
myMethod("Hello World");
function myMethod(someVariable) {
console.log(someVariable)
}
Now this will work from the command line:
node myFile.js

Node JS Error when copying file across partition. How to resolve this issue? [duplicate]

I'm trying to move a file from one partition to another in a Node.js script. When I used fs.renameSync I received Error: EXDEV, Cross-device link. I'd copy it over and delete the original, but I don't see a command to copy files either. How can this be done?
You need to copy and unlink when moving files across different partitions. Try this,
var fs = require('fs');
//var util = require('util');
var is = fs.createReadStream('source_file');
var os = fs.createWriteStream('destination_file');
is.pipe(os);
is.on('end',function() {
fs.unlinkSync('source_file');
});
/* node.js 0.6 and earlier you can use util.pump:
util.pump(is, os, function() {
fs.unlinkSync('source_file');
});
*/
I know this is already answered, but I ran across a similar problem and ended up with something along the lines of:
require('child_process').spawn('cp', ['-r', source, destination])
What this does is call the command cp ("copy"). Since we're stepping outside of Node.js, this command needs to be supported by your system.
I know it's not the most elegant, but it did what I needed :)
One more solution to the problem.
There's a package called fs.extra written by "coolaj86" on npm.
You use it like so:
npm install fs.extra
fs = require ('fs.extra');
fs.move ('foo.txt', 'bar.txt', function (err) {
if (err) { throw err; }
console.log ("Moved 'foo.txt' to 'bar.txt'");
});
I've read the source code for this thing. It attempts to do a standard fs.rename() then, if it fails, it does a copy and deletes the original using the same util.pump() that #chandru uses.
to import the module and save it to your package.json file
npm install mv --save
then use it like so:
var mv = require('mv');
mv('source_file', 'destination_file', function (err) {
if (err) {
throw err;
}
console.log('file moved successfully');
});
I made a Node.js module that just handles it for you. You don't have to think about whether it's going to be moved within the same partition or not. It's the fastest solution available, as it uses the recent fs.copyFile() Node.js API to copy the file when moving to a different partition/disk.
Just install move-file:
$ npm install move-file
Then use it like this:
const moveFile = require('move-file');
(async () => {
await moveFile(fromPath, toPath);
console.log('File moved');
})();

How do I move file a to a different partition or device in Node.js?

I'm trying to move a file from one partition to another in a Node.js script. When I used fs.renameSync I received Error: EXDEV, Cross-device link. I'd copy it over and delete the original, but I don't see a command to copy files either. How can this be done?
You need to copy and unlink when moving files across different partitions. Try this,
var fs = require('fs');
//var util = require('util');
var is = fs.createReadStream('source_file');
var os = fs.createWriteStream('destination_file');
is.pipe(os);
is.on('end',function() {
fs.unlinkSync('source_file');
});
/* node.js 0.6 and earlier you can use util.pump:
util.pump(is, os, function() {
fs.unlinkSync('source_file');
});
*/
I know this is already answered, but I ran across a similar problem and ended up with something along the lines of:
require('child_process').spawn('cp', ['-r', source, destination])
What this does is call the command cp ("copy"). Since we're stepping outside of Node.js, this command needs to be supported by your system.
I know it's not the most elegant, but it did what I needed :)
One more solution to the problem.
There's a package called fs.extra written by "coolaj86" on npm.
You use it like so:
npm install fs.extra
fs = require ('fs.extra');
fs.move ('foo.txt', 'bar.txt', function (err) {
if (err) { throw err; }
console.log ("Moved 'foo.txt' to 'bar.txt'");
});
I've read the source code for this thing. It attempts to do a standard fs.rename() then, if it fails, it does a copy and deletes the original using the same util.pump() that #chandru uses.
to import the module and save it to your package.json file
npm install mv --save
then use it like so:
var mv = require('mv');
mv('source_file', 'destination_file', function (err) {
if (err) {
throw err;
}
console.log('file moved successfully');
});
I made a Node.js module that just handles it for you. You don't have to think about whether it's going to be moved within the same partition or not. It's the fastest solution available, as it uses the recent fs.copyFile() Node.js API to copy the file when moving to a different partition/disk.
Just install move-file:
$ npm install move-file
Then use it like this:
const moveFile = require('move-file');
(async () => {
await moveFile(fromPath, toPath);
console.log('File moved');
})();

Categories

Resources