knex.js - migration fails for dynamic schema name - node.js

Environment
Knex version: knex#0.16.3
Database + version: MySQL 5.7.24
OS: Linux (Manjaro)
Bug
I'm trying to setup an integration test suite using ava. As known, ava spawns different Node processes for each test file.
In order to make the tests isolated, I need to re-create my database and run the migrations in all test files. I started bootstrapping and got the following script:
import test from 'ava';
import cuid from 'cuid';
import knexFactory from 'knex';
import knexFile from './knexfile';
const knex = knexFactory(knexFile.development);
test.before(async t => {
const schemaName = `foo_${cuid()}`;
await knex.raw(`CREATE SCHEMA ${schemaName}`);
try {
await knex.migrate.latest({ schemaName });;
} catch (err) {
}
Object.assign(t.context, { schemaName });
});
test.after.always(async t => {
const { schemaName } = t.context;
await knex.raw(`DROP SCHEMA ${schemaName}`);
});
test('foo', () => {})
However, I'm running into the following error:
migration file "20190205110315_create_users_table.js" failed
migration failed with error: create table users (id int unsigned not null auto_increment primary key, email varchar(255), password text) - Table 'users' already exists
What is happening is that the .migrate.latest() call is ignoring its schemaName parameter and it's running against the configuration defined in the knexfile.js file, that is, the actual database.
The migration file is pretty straightforward:
exports.up = function(knex, Promise) {
return knex.schema.createTable('users', table => {
table.increments();
table.string('email');
table.text('password');
})
};
exports.down = function(knex, Promise) {
return knex.schema.dropTable('users');
};

Related

Error: Module name "cassandra-driver" has not been loaded yet for context: _. Use require([])

I am using datastax cassandra-driver to make a database.
This is connect-database:
import { require } from "./requirejs.mjs";
export async function run() {
const { Client } = require("cassandra-driver");
const client1 = new Client({
cloud: {
get secureConnectBundle(){
return "secure-connect-amazonfeud.zip"}
},
credentials: {
get username(){
return "<my username>"},
get password(){
return "<my password>"}
},
});
await client1.connect();
const rs = await client1.execute("SELECT * FROM feud.users");
const results = await client1.execute("update feud.users set score=250 where id=1")
console.log(rs['rows'][0])
console.log(`Your cluster returned ${rs.rowLength} row(s)`);
await client1.shutdown();
}
This is main.js:
import { run } from "./connect-database.mjs";
run()
When I run connect-database.mjs, it works, but when I run main.js it gives me error "Uncaught Error Error: Module name "cassandra-driver" has not been loaded yet for context: _. Use require([])
https://requirejs.org/docs/errors.html#notloaded"
When I change the format to be require[], it says "Uncaught TypeError TypeError: Client is not a constructor"
Please help
If you're using a custom require in order to require cassandra-driver, you don't need to do that. Client function is exposed using module.exports in cassandra-driver so you can use a simple import.
An example that worked for me:
cassandraDriverTest.mjs
import { Client } from 'cassandra-driver';
import { inspect } from 'util';
const client = new Client({
contactPoints: ['cp'],
localDataCenter: 'dc1',
keyspace: 'ks'
});
const query = '<query>';
client.execute(query)
.then(result => console.log('User with email %s', result.rows[0].some_data,));
console.log(inspect(client));

TypeORM and MongoDB and Repositories: Cannot read property 'prototype' of undefined

I'm trying implement TypeORM with MongoDB using repositories. However, when I try to make use of repositories to manage the database, using the same structure as in this repository, things go a bit sideways. I'm getting the following error:
UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'prototype' of undefined
I have tried the following code:
import { Request, Response } from 'express';
import { getMongoRepository } from "typeorm";
import Task from "../models/Task";
export default class TasksController {
async listAll(request: Request, response: Response): Promise<Response> {
const tasksRepository = getMongoRepository(Task);
try {
const tasks = await tasksRepository.find();
return response.status(200).json({ "items": tasks });
} catch (err) {
return response.status(400).json({
message: err.message,
});
}
}
}
I know the error refers to implementing the .find() method. I have even managed to fetch the data, using a suggestion from this post replacing:
const tasks = await tasksRepository.find();
with
const tasks = await tasksRepository.createCursor(tasksRepository.find()).toArray();
but I still get the above mentioned error.
Anyone understands what's going on?
I have also managed to save data directly to the database through the use of the following script:
server.ts
import express from 'express';
import { createConnection } from 'typeorm'
const app = express();
const port = 3333;
createConnection();
app.use(express.json());
app.post('/tasks', (async (request, response) => {
const { item } = request.body;
task.item = item;
const task = new Task();
(await connection).mongoManager.save(task);
return response.send(task);
}))
app.listen(port, () =>
console.log(`Server running on port ${port}`)
);
TypeORM is not support mongodb v4.
https://github.com/nestjs/nest/issues/7798
You can use 3.7.0 instead.
I submitted a pull requests to resolve this. https://github.com/typeorm/typeorm/pull/8412 if anyone is looking for a workaround in the meantime.

Next.js - using BigQuery client library gives an error : Module not found: Can't resolve 'child_process'

I am trying to query bigQuery dataset from a next.js project.
I have installed #google-cloud/bigquery and followed the steps from here
I have also tried next.js related solutions from this link but still getting below error.
It looks like next.config.js needs to be configured for this to allow this api call. I am not sure what needs to be changed.
Could someone please help me resolve this issue?
here is my code :
const { BigQuery } = require("#google-cloud/bigquery");
const bigquery = new BigQuery();
useEffect(() => {
async function queryBigQuery() {
const query = `
SELECT fieldname
FROM \`db.dataset.tablename\` WHERE columnname = 50
LIMIT 10`;
const options = {
query: query,
};
// Run the query
const [rows] = await bigquery.query(options);
console.log("Query Results:");
rows.forEach((row) => {
const url = row["url"];
const viewCount = row["view_count"];
console.log(`url: ${url}, ${viewCount} views`);
});
}
queryBigQuery();
}, []);
**wait - compiling...
error - ./node_modules/google-auth-library/build/src/auth/googleauth.js:17:0
Module not found: Can't resolve 'child_process'**
UPDATED:
I am able to load bigQuery library I think on client side but its giving me new error.
Here is my latest next.config.js file
module.exports = {
webpack: (config, { isServer, webpack }) => {
if (!isServer) {
config.node = {
dgram: "empty",
fs: "empty",
net: "empty",
tls: "empty",
child_process: "empty",
};
}
return config;
},
env: {
project variables.
};
New Error:
#google-cloud/bigquery is meant to run on a Node.js environment, it won't work in the browser.
You'll need to move your code to a data fetching method like getStaticProps/getServerSideProps or to an API route, as they all run server-side.
Here's an example using an API route, as it seems to fit your use-case best.
// pages/api/bigquery
const { BigQuery } = require("#google-cloud/bigquery");
const bigquery = new BigQuery();
export default function handler(req, res) {
const query = `
SELECT fieldname
FROM \`db.dataset.tablename\` WHERE columnname = 50
LIMIT 10
`;
const options = {
query: query,
};
// Run your query/logic here
res.json(data); // Return your JSON data after logic has been applied
}
Then, in your React component's useEffect:
const queryBigQuery = async () => {
const res = await fetch('api/bigquery');
const data = await res.json(); // Returns JSON data from API route
console.log(data);
}
useEffect(() => {
queryBigQuery();
}, []);

Need to find the error with connecting subscription with schema stitching

I am using apollo-server-express for graphql back-end. I am going to process only mutations there, but I want to redirect query and subscription on hasura by means of schema stitching with introspection. Queries through apollo-server to hasura are working fine and returning the expected data.
But subscriptions are not working and I am getting this error: " Expected Iterable, but did not find one for field subscription_root.users".
And besides, server hasura is receiving events:
But apollo-server resents the answer from hasura. It is not the first day I suffer with this and I can not understand what the problem is.
In the editor hasura subscriptions work.
Link to full code
If you need any additional info, I will gladly provide it to you.
import {
introspectSchema,
makeExecutableSchema,
makeRemoteExecutableSchema,
mergeSchemas,
transformSchema,
FilterRootFields
} from 'graphql-tools';
import { HttpLink } from 'apollo-link-http';
import nodeFetch from 'node-fetch';
import { resolvers } from './resolvers';
import { hasRoleResolver } from './directives';
import { typeDefs } from './types';
import { WebSocketLink } from 'apollo-link-ws';
import { split } from 'apollo-link';
import { getMainDefinition } from 'apollo-utilities';
import { SubscriptionClient } from 'subscriptions-transport-ws';
import * as ws from 'ws';
import { OperationTypeNode } from 'graphql';
interface IDefinitionsParams {
operation?: OperationTypeNode,
kind: 'OperationDefinition' | 'FragmentDefinition'
}
const wsurl = 'ws://graphql-engine:8080/v1alpha1/graphql';
const getWsClient = function (wsurl: string) {
const client = new SubscriptionClient(wsurl, {
reconnect: true,
lazy: true
}, ws);
return client;
};
const wsLink = new WebSocketLink(getWsClient(wsurl));
const createRemoteSchema = async () => {
const httpLink = new HttpLink({
uri: 'http://graphql-engine:8080/v1alpha1/graphql',
fetch: (nodeFetch as any)
});
const link = split(
({ query }) => {
const { kind, operation }: IDefinitionsParams = getMainDefinition(query);
console.log('kind = ', kind, 'operation = ', operation);
return kind === 'OperationDefinition' && operation === 'subscription';
},
wsLink,
httpLink,
);
const remoteSchema = await introspectSchema(link);
const remoteExecutableSchema = makeRemoteExecutableSchema({
link,
schema: remoteSchema
});
const renamedSchema = transformSchema(
remoteExecutableSchema,
[
new FilterRootFields((operation, fieldName) => {
return (operation === 'Mutation') ? false : true; // && fieldName === 'password'
})
]
);
return renamedSchema;
};
export const createNewSchema = async () => {
const hasuraExecutableSchema = await createRemoteSchema();
const apolloSchema = makeExecutableSchema({
typeDefs,
resolvers,
directiveResolvers: {
hasRole: hasRoleResolver
}
});
return mergeSchemas({
schemas: [
hasuraExecutableSchema,
apolloSchema
]
});
};
Fixed by installing graphql-tools 4th version. It tutns out the editor did not even notice that I do not have this dependency and simply took the version of node_modules, which was installed by some other package. Problem was with version 3.x. Pull request is where the bug was fixed.
I had the same problem, different cause and solution.
My subscription was working well, until I introduced the 'resolve' key in
my subscription resolver:
Here is the 'Subscription' part of My resolver:
Subscription: {
mySubName: {
resolve: (payload) => {
console.log('In mySubName resolver, payload:',payload)
return payload;
},
subscribe:() => pubSub.asyncIterator(['requestsIncomplete']),
// )
},
The console.log proved the resolve() function was being called with a well structured payload (shaped the same as my Schema definiton - specifically the an object with a key named after the graphQL Subscriber, pointing to an array (array is an iterable):
In mySubName resolver, payload: { mySubName:
[ { id: 41,
...,
},
{...},
{...}
...
...
]
Even though I was returning that same unadulterated object, it caused the error expected Iterable, but did not find one for field "Subscription.mySubName"
When I commented out that resolve function all together, the subscription worked, which is further evidence that my payload was well structured, with the right key pointing to an iterable.
I must be mis-using the resolve field. From https://www.apollographql.com/docs/graphql-subscriptions/subscriptions-to-schema/
When using subscribe field, it's also possible to manipulate the event
payload before running it through the GraphQL execution engine.
Add resolve method near your subscribe and change the payload as you wish
so I am not sure how to properly use that function, specifically don't know what shape object to return from it, but using it as above breaks the subscription in the same manner you describe in your question.
I was already using graphql-tools 4.0.0, I upgraded to 4.0.8 but it made no difference.

Mocking apollo graphql client

I have written the following node client which interacts with the graphql server and using apollo-tools node module. I was not able to find any mock test for the below in node. Pls let me know is there a way to mock the below piece of code.
const batchIdFetchClient = new ApolloClient({
uri: `http://localhost:3435`,
fetch,
})
await batchfetchclient.query({
query: gql`
query batcidId($batchid: String!) {
batchIds(batchid: $batchid){
batchrenewedId
}
}
`,
variables: {
batchid: 'exdsfsdfsfdid1234', // As of now hardcoded
},
})
.then(data => {
logger.info('BatchId Database Successful Response =>' + JSON.stringify(data))
})
.catch(error => {
logger.error('BatchId Database Error Response =>' + error)
})
Maybe you can try using easygraphql-tester, it'll be something like this:
You need to pass your schema in order to mock it
const EasyGraphQLTester = require('easygraphql-tester')
const tester = new EasyGraphQLTester(schema)
const query = gql`
query batcidId($batchid: String!) {
batchIds(batchid: $batchid){
batchrenewedId
}
}
`
const mock = tester.mock({
query,
variables: {
batchid: 'exdsfsdfsfdid1234', // As of now hardcoded
}
})
console.log(mock)
Also, you can set fixtures if you want to have a specific data.

Resources