How to delete a record and any relationship records in an explicit many to many relationship? - many-to-many

I'm struggling to find documentation for handling explicit many to many relationships in Prisma. So I have resorted to dev by Stackoverflow....
I have a many to many relationship:
model Fight {
id Int #id #default(autoincrement())
name String
fighters FighterFights[]
}
model Fighter {
id Int #id #default(autoincrement())
name String #unique
fights FighterFights[]
}
model FighterFights {
fighter Fighter #relation(fields: [fighterId], references: [id])
fighterId Int
fight Fight #relation(fields: [fightId], references: [id])
fightId Int
##id([fighterId, fightId])
}
I am trying to delete a fight and delete the relationship in FighterFights but not delete the actual fighter.
I tried the following:
const result = await prisma.fight.delete({
where: {
id: Number(id),
},
})
but get the error:
PrismaClientKnownRequestError:
Invalid `prisma.fight.delete()` invocation:
Foreign key constraint failed on the field: `FighterFights_fightId_fkey (index)`
I then also tried:
const result = await prisma.fight.delete({
where: { id: Number(id) },
data: {
fighterFights: {
deleteMany: {
where: { fightId: id },
},
},
},
})
But I get the error:
PrismaClientValidationError:
Invalid `prisma.fight.delete()` invocation:
{
where: {
id: 1
},
data: {
~~~~
fighterFights: {
deleteMany: {
where: {
fightId: '1'
}
}
}
}
}
Unknown arg `data` in data for type Fight. Available args:
type deleteOneFight {
where: FightWhereUniqueInput
}
I also tried:
const result = await prisma.fight.delete({
where: {
id: Number(id),
},
data: {
fighterFights: {
deleteMany: [{ fightId: { equals: Number(id) } }],
},
},
})
but get the error:
Invalid `prisma.fight.delete()` invocation:
{
where: {
id: 1
},
data: {
~~~~
fighterFights: {
deleteMany: [
{
fightId: {
equals: 1
}
}
]
}
}
}
Unknown arg `data` in data for type Fight. Available args:
type deleteOneFight {
where: FightWhereUniqueInput
}

Here is the Prisma documentation to disconnect related fields
For single disconnect
const updatePost = await prisma.user.update({
where: {
id: 16,
},
data: {
posts: {
disconnect: [{ id: 12 }, { id: 19 }],
},
},
select: {
posts: true,
},
})
To disconnect all
const updateUser = await prisma.user.update({
where: {
id: 16
},
data: {
posts: {
set: []
}
},
include: {
posts: true
}
})

here you go a way to do that:
const { PrismaClient } = require('#prisma/client')
const prisma = new PrismaClient()
const saveData = async () => {
const fighter1 = await prisma.fighter.create({
data: {
name: 'Ryu',
},
})
const fighter2 = await prisma.fighter.create({
data: {
name: 'Ken',
},
})
console.log('FIGHTERS');
console.log(JSON.stringify(fighter1, null, 2));
console.log(JSON.stringify(fighter2, null, 2));
const fight = await prisma.fight.create({
data: {
name: 'Ryu vs Ken',
fighters: {
createMany: {
data: [
{
fighterId: fighter1.id,
},
{
fighterId: fighter2.id,
},
]
},
},
},
select: {
id: true,
fighters: {
select: {
fighter: true,
},
},
},
});
console.log('FIGHTS');
console.log(JSON.stringify(await prisma.fight.findMany({ include: { fighters: true } }), null, 2));
const fighterFightsToDelete = prisma.fighterFights.deleteMany({
where: {
fightId: fight.id,
}
})
const fightToDelete = prisma.fight.delete({
where: {
id: fight.id,
}
})
await prisma.$transaction([ fighterFightsToDelete, fightToDelete ])
console.log('RESULT');
console.log(JSON.stringify(await prisma.fight.findMany({ include: { fighters: true } }), null, 2));
console.log(JSON.stringify(await prisma.fighter.findMany({ include: { fights: true } }), null, 2));
}
saveData()
And the result is the following :)

Related

I'm trying to join 3 tables in node.js using sequelize but having trouble. What is the problem with my code?

Newer to Node.js any advice would be appreciated! Trying to join 3 tables with a common key but getting the error...
react_devtools_backend.js:4026 [GraphQL error]: Message: Unknown column 'google_responsive_descriptions.googleTextAdId' in 'on clause', Location: [object Object], Path: listGoogleTextAds
googleResponsiveAds.js file
module.exports = (sequelize, DataTypes) => {
const googleResponsiveAds = sequelize.define(
"google_responsive_headlines",
{
responsive_headlines: { type: DataTypes.STRING },
responsive_path_1: { type: DataTypes.STRING },
responsive_path_2: { type: DataTypes.STRING }
},
{
timestamps: false,
tableName: "google_responsive_headlines"
}
);
//googleResponsiveAds.associate = () => {};
googleResponsiveAds.associate = function (models) {
googleResponsiveAds.belongsTo(models.google_text_ads, { foreignKey: "ad_id" });
}
return googleResponsiveAds;
};
googleResponsiveDescriptionsAds.js file
module.exports = (sequelize, DataTypes) => {
const googleResponsiveDescriptionsAds = sequelize.define(
"google_responsive_descriptions",
{
responsive_descriptions: { type: DataTypes.STRING }
},
{
timestamps: false,
tableName: "google_responsive_descriptions"
}
);
//googleResponsiveDescriptionsAds.associate = () => {};
googleResponsiveDescriptionsAds.associate = function (models) {
googleResponsiveDescriptionsAds.belongsTo(models.google_text_ads, { foreignKey: "ad_id" });
}
return googleResponsiveDescriptionsAds;
};
googleTextAds.js file
module.exports = (sequelize, DataTypes) => {
const googleTextAds = sequelize.define(
"google_text_ads",
{
headline_pt_1: { type: DataTypes.STRING },
headline_pt_2: { type: DataTypes.STRING },
headline_pt_3: { type: DataTypes.STRING },
final_url: { type: DataTypes.STRING },
display_url: { type: DataTypes.STRING },
status: { type: DataTypes.STRING },
type: { type: DataTypes.STRING },
description1: { type: DataTypes.STRING },
description2: { type: DataTypes.STRING },
path1: { type: DataTypes.STRING },
path2: { type: DataTypes.STRING },
ad_id: { type: DataTypes.INTEGER }
},
{
timestamps: false,
tableName: "google_text_ads"
}
);
//googleTextAds.associate = () => {};
googleTextAds.associate = function (models) {
googleTextAds.hasMany(models.google_responsive_headlines, { sourceKey: 'ad_id' })
googleTextAds.hasMany(models.google_responsive_descriptions, { sourceKey: 'ad_id' });
};
return googleTextAds;
};
Here is the section of the queries/google.js
{
key: "listGoogleTextAds",
prototype:
"(customer_id: Int, start_date: String, end_date: String): [GoogleTextAds]",
run: async args => {
const allIds = await google_text_ads
.findAll({
attributes: [
"ad_id",
"date",
"impressions",
"clicks",
"cost"
],
include: [
{
model: google_responsive_descriptions,
as: 'google_responsive_descriptions',
required: true,
attributes: [
"ad_id",
"responsive_descriptions"
],
},
{
model: google_responsive_headlines,
as: 'google_responsive_headlines',
attributes: [
"ad_id",
"responsive_headlines",
"responsive_path_1",
"responsive_path_2"
]
}
],
where: {
customer_id: args.customer_id,
date: {
[Op.gte]: args.start_date,
[Op.lte]: args.end_date
},
status: {
[Op.in]: ["ENABLED"]
},
type: {
[Op.in]: ["EXPANDED_TEXT_AD", "RESPONSIVE_SEARCH_AD"]
}
}
})
}
}
EDIT: Here's my query
export const LIST_GOOGLE_TEXT_ADS = gql`
query listGoogleTextAds(
$customer_id: Int!
$start_date: String!
$end_date: String!
) {
listGoogleTextAds(
customer_id: $customer_id
start_date: $start_date
end_date: $end_date
) {
ad_id
type
headline_pt_1
headline_pt_2
headline_pt_3
description1
description2
path1
path2
status
final_url
display_url
impressions
clicks
cost
}
}
`;
and my models...
type GoogleTextAds {
ad_id: Int
type: String
headline_pt_1: String
headline_pt_2: String
headline_pt_3: String
description1: String
description2: String
path1: String
path2: String
final_url: String
display_url: String
status: String
impressions: Int
clicks: Int
cost: Float
}
type GoogleResponsiveAds{
ad_id: Int
responsive_headlines: String
responsive_path_1: String
responsive_path_2: String
}
type GoogleResponsiveDescriptionsAds{
ad_id: Int
responsive_descriptions: String
}
here is the query I am trying to replicate...
SELECT distinct google_responsive_headlines.responsive_headlines,
google_responsive_headlines.responsive_path_1,
google_responsive_headlines.responsive_path_2,
google_responsive_descriptions.responsive_descriptions,
google_text_ads.date,
google_text_ads.clicks,
google_text_ads.cost,
google_text_ads.impressions,
google_text_ads.ad_id,
google_text_ads.status,
google_text_ads.final_url,
google_text_ads.create_time
FROM irene_db.google_text_ads
inner JOIN irene_db.google_responsive_headlines ON google_responsive_headlines.ad_id = google_text_ads.ad_id
inner JOIN irene_db.google_responsive_descriptions ON google_responsive_descriptions.ad_id = google_text_ads.ad_id
where google_text_ads.customer_id = 144 and google_text_ads.date = '2022-06-09' and
google_responsive_headlines.customer_id = 144 and google_responsive_headlines.date = '2022-06-09' and
google_responsive_descriptions.customer_id = 144 and google_responsive_descriptions.date = '2022-06-09';
EDIT2: Where associate gets called...
const fs = require("fs");
const path = require("path");
const Sequelize = require("sequelize");
const dotenv = require("dotenv");
dotenv.config();
const basename = path.basename(module.filename);
const db = {};
let sequelize;
const { DB_HOST, DB_USER, DB_PASS, DB_NAME } = process.env;
sequelize = new Sequelize(DB_NAME, DB_USER, DB_PASS, {
dialect: "mysql",
host: DB_HOST
});
fs.readdirSync(__dirname)
.filter(
file =>
file.indexOf(".") !== 0 && file !== basename && file.slice(-3) === ".js"
)
.forEach(file => {
const model = sequelize.import(path.join(__dirname, file));
db[model.name] = model;
});
Object.keys(db).forEach(modelName => {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
module.exports = db;
EDIT 3:
After boc4life's code suggestions I'm now at least getting graphql to attempt the query. But it's using the wrong field name in the join on section. Here's the query it built...
SELECT
`google_text_ads`.`id`,
`google_text_ads`.`ad_id`,
`google_text_ads`.`date`,
`google_text_ads`.`impressions`,
`google_text_ads`.`clicks`,
`google_text_ads`.`cost`,
`google_responsive_descriptions`.`id` AS `google_responsive_descriptions.id`,
`google_responsive_descriptions`.`responsive_descriptions` AS `google_responsive_descriptions.responsive_descriptions`,
`google_responsive_headlines`.`id` AS `google_responsive_headlines.id`,
`google_responsive_headlines`.`responsive_headlines` AS `google_responsive_headlines.responsive_headlines`,
`google_responsive_headlines`.`responsive_path_1` AS `google_responsive_headlines.responsive_path_1`,
`google_responsive_headlines`.`responsive_path_2` AS `google_responsive_headlines.responsive_path_2`
FROM
`google_text_ads` AS `google_text_ads`
INNER JOIN
`google_responsive_descriptions` AS `google_responsive_descriptions` ON `google_text_ads`.`ad_id` = `google_responsive_descriptions`.`googleTextAdId`
INNER JOIN
`google_responsive_headlines` AS `google_responsive_headlines` ON `google_text_ads`.`ad_id` = `google_responsive_headlines`.`googleTextAdId`
WHERE
`google_text_ads`.`customer_id` = 142
AND (`google_text_ads`.`date` >= '2022-05-17'
AND `google_text_ads`.`date` <= '2022-06-17')
AND `google_text_ads`.`status` IN ('ENABLED')
AND `google_text_ads`.`type` IN ('EXPANDED_TEXT_AD' , 'RESPONSIVE_SEARCH_AD');
Try using the tableName defined while defining the table structure to access the model while creating associations.
Example: instead of
models.googleTextAds
do
models.google_text_ads
What jumps out to me is all of those nested includes. Since you are joining the Headlines and Descriptions tables on the Text_Ads table, I believe all you should need here is the one include array containing two objects, one for Headlines and one for Descriptions.
Currently you have Headlines nested under Descriptions, which won't work because Descriptions does not have an association with Headlines directly defined. You also have an include of Text_Ads nested inside of Descriptions, which should WORK, but should be unnecessary since that is the model you are calling findAll() on. You can bring the Text_Ads attributes you are querying for out into that parent object as a sibling of include. Something like this looks like a good starting point for getting the query cleaned up. I have also removed a bunch of the unnecessary sequelize.col() that you had in your initial post.
const allIds = await google_text_ads
.findAll({
attributes: [
"ad_id",
[sequelize.fn("max", sequelize.col("date")), "date"],
[sequelize.fn("sum", sequelize.col("impressions")), "impressions"],
[sequelize.fn("sum", sequelize.col("clicks")), "clicks"],
[sequelize.fn("sum", sequelize.col("cost")), "cost"]
],
include: [
{
model: Models.google_responsive_descriptions,
as: 'googleResponsiveDescriptionsAds',
required: true,
attributes: [
"ad_id",
"responsive_descriptions"
],
},
{
model: Models.google_responsive_headlines,
as: 'googleResponsiveAds',
attributes: [
"ad_id",
"responsive_headlines",
"responsive_path_1",
"responsive_path_2"
]
}
],
where: {
customer_id: args.customer_id,
date: {
[Op.gte]: args.start_date,
[Op.lte]: args.end_date
},
status: {
[Op.in]: ["ENABLED"]
},
type: {
[Op.in]: ["EXPANDED_TEXT_AD", "RESPONSIVE_SEARCH_AD"]
}
}
})

How to update a many to many relationship in Prisma?

I am modelling a boxing tournament.
Boxers and Fights have a many-to-many relationship:
A Boxer has many Fights
A Fight has many Boxers (exactly 2)
Here are the models in the schema
model Fight {
id Int #id #default(autoincrement())
name String
boxers BoxerFights[]
}
model Boxer {
id Int #id #default(autoincrement())
name String #unique
fights BoxerFights[]
}
model BoxerFights {
boxer Boxer #relation(fields: [boxerId], references: [id])
boxerId Int
fight Fight #relation(fields: [fightId], references: [id])
fightId Int
##id([boxerId, fightId])
}
When creating a boxer I use the fight's name and the 2 boxer ids:
const fight = await prisma.fight.create({
data: {
name,
boxers: {
createMany: {
data: [
{
boxerId: boxerId1,
},
{
boxerId: boxerId2,
},
],
},
},
},
})
How would I update the fight if a boxer needed to be changed? Something like this? I'm not sure if I use update and set
const fight = await prisma.fight.update({
data: {
name: newName,
boxers: {
set: {
data: [
{
boxerId: newBoxerId1,
},
{
boxerId: newBoxerId2,
},
],
},
},
},
})
Here you go an example how to do that:
const { PrismaClient } = require('#prisma/client')
const prisma = new PrismaClient()
const saveData = async () => {
const boxer1 = await prisma.boxer.create({
data: {
name: 'Boxer1',
},
})
const boxer2 = await prisma.boxer.create({
data: {
name: 'Boxer2',
},
})
const fight = await prisma.fight.create({
data: {
name: 'Fight 1',
boxers: {
createMany: {
data: [
{ boxerId: boxer1.id },
{ boxerId: boxer2.id },
]
},
}
},
select: {
id: true,
name: true,
boxers: {
select: {
boxer: {
select: {
name: true,
}
}
}
}
}
})
console.log(JSON.stringify(fight, null, 2))
const boxer3 = await prisma.boxer.create({
data: {
name: 'Boxer3',
},
})
const fightUpdated = await prisma.fight.update({
where: {
id: fight.id
},
data: {
boxers: {
createMany: {
data: [
{ boxerId: boxer3.id },
]
},
deleteMany: {
OR: [
{ boxerId: { equals: boxer1.id } },
]
}
}
},
select: {
name: true,
boxers: {
select: {
boxer: {
select: {
name: true,
}
}
}
}
}
})
console.log(JSON.stringify(fightUpdated, null, 2))
}
saveData()
In the update you have to remove the previous boxer and the new one :)

GraphQL - operating elements of array

I would like to display some information about members, but I don't know how to resolve array of field 'time'. This is array, because it shows their login time. What should I do?
I used GraphQLString, but I am aware of this bad solution.
So I'm getting an error:
"message": "String cannot represent value: [\"12:08\"]",
Here is schema.js
const axios = require("axios");
const {
GraphQLObjectType,
GraphQLString,
GraphQLList,
GraphQLSchema
} = require("graphql");
const memberType = new GraphQLObjectType({
name: "Member",
fields: () => ({
nick: {
type: GraphQLString
},
name_and_surname: {
type: GraphQLString
},
time: {
type: GraphQLString
}
})
});
//Root Query
const RootQuery = new GraphQLObjectType({
name: "RootQueryType",
fields: {
users: {
type: new GraphQLList(memberType),
description: "List of members",
resolve(parent, args) {
return axios
.get("http://25.98.140.121:5000/data")
.then(res => res.data);
}
}
}
})
module.exports = new GraphQLSchema({
query: RootQuery
});
And here is JSON
[
{
"time": [
"12:08"
],
"nick": "Cogi12",
"name_and_surname: "John Steps"
},
{
"time": [
"12:16"
],
"nick": "haris22",
"name_and_surname": "Kenny Jobs"
},
{
"time": [
"12:07",
"12:08",
"12:17",
"12:19",
"12:45",
"13:25"
],
"nick": "Wonski",
"name_and_surname": "Mathew Oxford"
}
]
you can use GraphQLList along with GraphQLString for time type like this,
const memberType = new GraphQLObjectType({
name: "Member",
fields: () => ({
nick: {
type: GraphQLString
},
name_and_surname: {
type: GraphQLString
},
time: {
type: new GraphQLList(GraphQLString)
}
})
});

Custom type in GraphQL mutation

I am using GraphQL js.I want to implement One-to-many association in it.I have two types user and Office.One user has many offices.
userType:
var graphql = require('graphql');
const userType = new graphql.GraphQLObjectType({
name: 'user',
fields :()=>{
var officeType=require('./officeSchema');
return {
_id: {
type: graphql.GraphQLID
},
name: {
type: graphql.GraphQLString
},
age: {
type: graphql.GraphQLString
},
office:{
type:officeType
}
};
}
});
module.exports=userType;
officeSchema:
const officeType = new graphql.GraphQLObjectType({
name: 'office',
fields:()=> {
var userType = require('./userSchema');
return {
_id: {
type: graphql.GraphQLID
},
room: {
type: graphql.GraphQLString
},
location: {
type: graphql.GraphQLString
},
users: {
type: new graphql.GraphQLList(userType),
resolve: (obj,{_id}) => {
fetch('http://0.0.0.0:8082/office/user/'+obj._id, {
method: "GET",
headers: {
'Content-Type': 'application/json'
}
})
.then(function(res) {return res});
}
}
};
}
});
Now the mutation code is as follows:
const Adduser = {
type: userType,
args: {
name: {
type: graphql.GraphQLString
},
age: {
type: graphql.GraphQLString
}
},
resolve: (obj, {
input
}) => {
}
};
const Addoffice = {
type: OfficeType,
args: {
room: {
type: graphql.GraphQLString
},
location: {
type: graphql.GraphQLString
},
users: {
type: new graphql.GraphQLList(userInputType)
}
},
resolve: (obj, {
input
}) => {
}
};
const Rootmutation = new graphql.GraphQLObjectType({
name: 'Rootmutation',
fields: {
Adduser: Adduser,
Addoffice: Addoffice
}
});
This code is throwing error as
Rootmutation.Addoffice(users:) argument type must be Input Type but got: [user].
I want to add the actual fields in database as well as associated tables' fields but couldn't figure out the problem.
Updated:
1-Added GraphQLInputObjectType:
const officeInputType = new graphql.GraphQLInputObjectType({
name: 'officeinput',
fields: () => {
return {
room: {
type: graphql.GraphQLString
},
location: {
type: graphql.GraphQLString
}
}
}
});
const userInputType = new graphql.GraphQLInputObjectType({
name: 'userinput',
fields: () => {
return {
name: {
type: graphql.GraphQLString
},
age: {
type: graphql.GraphQLString
}
}
}
});
2-Added userinputtype instead of usertype in AddOffice.
Now the error is
Rootmutation.Addoffice(user:) argument type must be Input Type but got: userinput.
The problem is that you provided userType as one of the argument types for the Addoffice mutation. userType cannot be an argument type. Instead, you must use an input type.
There are two object types: output and input types. Your userType and officeType are output types. You need to create an input type using GraphQLInputObjectType [docs]. It will likely have very similar fields. You can use that as a type on your argument field.
const userInputType = new graphql.GraphQLInputObjectType({
name: 'UserInput',
fields () => {
return {
_id: {
type: graphql.GraphQLID
},
// ...
};
}
});

Nested arrays in object json to csv

Im using 'json-csv' library to create a csv from a users arrays with nested objects and arrays.
var users = [
{
subscriptions: [
{
package : {
name: 'Grammar'
},
state: 'EXPIRED',
timerange: {
period : 5550
},
transaction:{
amount: 10000
}
},
{
package : {
name: 'GK'
},
state: 'ACTIVE',
timerange: {
period : 30
},
transaction:{
amount: 10340
}
},
],
account:{
balance: 200
},
name: "Johhy Moe",
email: null,
user_id: "123456789",
username: null,
user_type: "facebook",
id: 3,
createdAt: "2016-07-11T08:02:40.000Z",
updatedAt: "2016-07-11T08:02:40.000Z",
},
{
subscriptions: [
{
package : {
name: 'GK'
},
state: 'EXPIRED',
timerange: {
period : 42
},
transaction:{
amount: 5252
}
},
{
package : {
name: 'MATH'
},
state: 'ACTIVE',
timerange: {
period : 25
},
transaction:{
amount: 200
}
}
],
account:{
balance: 1500
},
name: "John Doe",
email: null,
user_id: "123456789",
username: null,
user_type: "facebook",
id: 7,
createdAt: "2016-07-29T06:44:18.000Z",
updatedAt: "2016-07-29T06:44:18.000Z"
},
]
Now i want the generated csv to be like this
USERID,NAME,FBID,ACCOUNT,SUBSCRIPTION,PRICE,STATE,TIMEPERIOD
3,Johhy Moe,123456789,200,Grammar,10000,EXPIRED,5550
3,Johhy Moe,123456789,200,GK,10340,ACTIVE,30
7,John Doe,123456789,1500,GK,5252,EXPIRED,30
7,John Doe,123456789,1500,MATH,200,ACTIVE,25
As you see if there are two objects inside subscription array for each user, i want to repeat that user again but with different subscription data.
I've thought of using the library because my users array can go up to thousands of users with hundreds of subscription.
And i'm at a loss to what i should do.
my Code:
var options= {
fields : [
{
name : 'id',
label : 'USERID'
},
{
name : 'name',
label : 'Name'
},
{
name : 'user_id',
label : 'FBID'
},
{
name : 'account.balance',
label : 'ACCOUNT'
},
{
name: '',
label: 'Subscription'
}
]
}
var source = es.readArray(users)
source
.pipe(jsoncsv.csv(options))
.pipe(res)
I dont want to use a library also. So if someone could provide me with a resource to make my own csv file with strings and also using streams , that would be great. Thanks!!
This will solve your problem. Now you just have to change console.log to fs and write to your file.
var json2csv = function (json, listKeys) {
var str = "";
var prefix = "";
for (var i = 0; i < listKeys.length; i++) {
str += prefix + json[listKeys[i]];
prefix = ",";
}
return str;
};
var async = require('async');
var csvData = ['USERID,NAME,FBID,ACCOUNT,SUBSCRIPTION,PRICE,STATE,TIMEPERIOD'];
async.each(users, function (user, callback) {
var csvRow1 = {
USERID: user.id,
NAME: user.name,
FBID: user.user_id,
ACCOUNT: user.account.balance
};
async.each(user.subscriptions, function (subscription, callback) {
var csvRow2 = JSON.parse(JSON.stringify(csvRow1));
csvRow2.SUBSCRIPTION = subscription.package.name;
csvRow2.PRICE = subscription.transaction.amount;
csvRow2.STATE = subscription.state;
csvRow2.TIMEPERIOD = subscription.timerange.period;
csvData.push(json2csv(csvRow2, ['USERID', 'NAME', 'FBID', 'ACCOUNT', 'SUBSCRIPTION', 'PRICE', 'STATE', 'TIMEPERIOD']));
callback(null);
}, function (err) {
callback(err);
});
}, function (err) {
if (err) {
// return err;
} else {
// return csvData;
}
});