I am getting the error from the title when I attempt to run relay-compiler in my project. I am using graphql-python/graphene-django for the back end graphql server. Here's an abbreviated copy of my schema.
grove.gql_schema.py:
from graphene_django import DjangoObjectType
from graphene_django.filter import DjangoFilterConnectionField
from .models import Tree
class TreeNode(DjangoObjectType):
class Meta:
model = Tree
filter_fields = ['owner']
interfaces = (relay.Node,)
class Query(ObjectType):
def resolve_my_trees(self, info):
if not info.context.user.is_authenticated:
return Tree.objects.none()
else:
return Tree.objects.filter(owner=info.context.user)
my_trees = DjangoFilterConnectionField(TreeNode)
tree = relay.Node.Field(TreeNode)
project.gql_schema:
class Query(grove.gql_schema.Query, graphene.ObjectType):
pass
schema = graphene.Schema(query=Query)
With that setup, I can successfully run the following query in GraphiQL
query {
myTrees {
edges {
node {
id
}
}
}
}
So far so good, but now I'm trying to build a client-side component that can use this query.
jsapp/components/index.jsx:
import React from 'react';
import {graphql, QueryRenderer} from 'react-relay';
import environment from '../relay_env'
const myTreesQuery = graphql`
query componentsMyTreesQuery {
edges {
node {
id
}
}
}
`;
export default class App extends React.Component {
render() {
return (
<QueryRenderer
environment={environment}
query={myTreesQuery}
variables={{}}
render={({error, props}) => {
if (error) {
return <div>Error!</div>;
}
if (!props) {
return <div>Loading...</div>;
}
return <div>User ID: {props.edges}</div>;
}}
/>
);
}
}
The query is identical, but when I run relay-compiler --src ./jsapp --schema ./schema.graphql --extensions js jsx I get the error:
GraphQLParser: Unknown field `edges` on type `Query`.
Source: document `componentsMyTreesQuery` file: `components/index.jsx`.
I get this error if when I use the .json schema generated by the Django graphaql_schema management command or the .graphql one retrieved by get-graphql-schema.
What part am I missing?
I might be a bit late but it looks to me like you're trying to ask for the edges on the root of your schema, the fragment:
const myTreesQuery = graphql`
query componentsMyTreesQuery {
edges {
node {
id
}
}
}
`;
I think could be altered to:
const myTreesQuery = graphql`
query componentsMyTreesQuery {
myTrees {
edges {
node {
id
}
}
}
}
`;
The text after the keyword query refers to the name of the 'query', not the root of the schema. If you're using Relay Modern (which by the use of QueryRenderer, I assume you are) then the compiler should yell at you to fix the name of your fragment to something that reflects the filename that it's stored in.
Related
I have two databases that I need to interact with in my code. I have a simple function that takes an object and writes it to my PostgreSQL database using Prisma. I've tested the function with Postman, and it works perfectly, but when I try to execute it using a Jest mock (using the singleton pattern found in the Prisma unit testing guide), it returns undefined indicating that it didn't interact with the database and create the new record. Here's my code:
/prisma/clinical-schema.prisma
generator client {
provider = "prisma-client-js"
output = "./generated/clinical"
}
datasource clinicalDatabase {
provider = "postgresql"
url = "postgresql://postgres:postgres#localhost:5432/clinical-data?schema=public"
}
model pcc_webhook_update {
id Int #id #default(autoincrement())
event_type String
organization_id Int
facility_id Int
patient_id Int
resource_id String?
webhook_date DateTime #default(now()) #clinicalDatabase.Timestamptz(6)
status pcc_webhook_update_status #default(pending)
status_changed_date DateTime? #clinicalDatabase.Timestamptz(6)
error_count Int #default(0)
##unique([organization_id, facility_id, patient_id, resource_id, event_type, status])
}
enum pcc_webhook_update_status {
pending
processing
processed
error
}
/prisma/clinical-client.ts
import { PrismaClient } from './generated/clinical';
const prismaClinical = new PrismaClient();
export default prismaClinical;
/testing/prisma-clinical-mock.ts
import { PrismaClient } from '../prisma/generated/clinical';
import { mockDeep, mockReset, DeepMockProxy } from 'jest-mock-extended';
import prisma from '../prisma/clinical-client';
jest.mock('../prisma/clinical-client', () => ({
__esModule: true,
default: mockDeep<PrismaClient>()
}));
beforeEach(() => {
mockReset(prismaClinicalMock);
});
export const prismaClinicalMock = prisma as unknown as DeepMockProxy<PrismaClient>;
Everything up to this point follows the conventions outlined by the Prisma unit testing docs. The only modification I made was to make it database specific. Below is my function and tests. The request object in handle-pcc-webhooks.ts is a sample http request object, the body of which contains the webhook data I care about.
/functions/handle-pcc-webhooks/handler.ts
import prismaClinical from '../../../prisma/clinical-client';
import { pcc_webhook_update } from '../../../prisma/generated/clinical';
import { requestObject } from './handler.types';
export const handlePccWebhook = async (request: requestObject) => {
try {
const webhook = JSON.parse(request.body);
// if the webhook doesn't include a resource id array, set it to an array with an empty string to ensure processing and avoid violating
// the multi-column unique constraint on the table
const { resourceId: resourceIds = [''] } = webhook;
let records = [];
for (const resourceId of resourceIds) {
// update an existing record if one exists in the pending state, otherwise create a new entry
const record: pcc_webhook_update = await prismaClinical.pcc_webhook_update.upsert({
where: {
organization_id_facility_id_patient_id_resource_id_event_type_status: {
organization_id: webhook.orgId,
facility_id: webhook.facId,
patient_id: webhook.patientId,
resource_id: resourceId,
event_type: webhook.eventType,
status: 'pending'
}
},
update: {
webhook_date: new Date()
},
create: {
event_type: webhook.eventType,
organization_id: webhook.orgId,
facility_id: webhook.facId,
patient_id: webhook.patientId,
resource_id: resourceId,
status: 'pending' // not needed
}
});
records.push(record);
}
return records;
} catch (error) {
console.error(error);
}
};
/functions/handle-pcc-webhooks/handler.spec.ts
import fs from 'fs';
import path from 'path';
import MockDate from 'mockdate';
import { prismaClinicalMock } from '../../../testing/prisma-clinical-mock';
import { createAllergyAddRecord } from './__mocks__/allergy';
import { requestObject } from './handler.types';
import { handlePccWebhook } from './handler';
describe('allergy.add', () => {
let requestObject: requestObject;
let allergyAddRecord: any;
beforeAll(() => {
requestObject = getRequestObject('allergy.add');
});
beforeEach(() => {
MockDate.set(new Date('1/1/2022'));
allergyAddRecord = createAllergyAddRecord(new Date());
});
afterEach(() => {
MockDate.reset();
});
test('should create an allergy.add database entry', async() => {
prismaClinicalMock.pcc_webhook_update.create.mockResolvedValue(allergyAddRecord);
// this is where I would expect handlePccWebhook to return the newly created database
// record, but instead it returns undefined. If I run the function outside of this
// unit test, with the same input value, it functions perfectly
await expect(handlePccWebhook(requestObject)).resolves.toEqual([allergyAddRecord]);
});
});
// This just builds a request object with the current webhook being tested
function getRequestObject(webhookType: string) {
// read the contents of request object file as a buffer, then convert it to JSON
const rawRequestObject = fs.readFileSync(path.resolve(__dirname, '../../sample-data/handle-pcc-webhook-request.json'));
const requestObject: requestObject = JSON.parse(rawRequestObject.toString());
// read the contents of the webhook file as a buffer, then convert it to a string
const rawWebhook = fs.readFileSync(path.resolve(__dirname, `../../sample-data/${webhookType}.json`));
const webhookString = rawWebhook.toString();
// set the body of the request object to the contents of the target webhook
requestObject.body = webhookString;
return requestObject;
}
Finally, here is the result of running the unit test:
So after banging my had against the wall for a few hours, I figured out the issue. In my handler.spec.ts file, I had the following line:
prismaClinicalMock.pcc_webhook_update.create.mockResolvedValue(allergyAddRecord);
what that does is mock the value returned for any create functions run using Prisma. The issue is that my function is using an upsert function, which I wasn't explicitly mocking, thus returning undefined. I changed the above line to
prismaClinicalMock.pcc_webhook_update.upsert.mockResolvedValue(allergyAddRecord);
and it started working.
I'm running into an issue where running a query with the useQuery Apollo hook works fine, but if I use the useApolloClient hook to get the instance of ApolloClient and then call the client's query method, the call fails with the error Error: query option is required. You must specify your GraphQL document in the query option.
My code more or less looks like this:
import React from 'react'
import gql from 'graphql-tag'
import { useQuery, useApolloClient } from '#apollo/react-hooks'
const MyComponent = props => {
const QUERY = gql`
query MyPersonSearch ( $after: String, $filter: PersonFilter, $first: Int ) {
people: people ( after: $after, filter: $filter, first: $first ) {
totalCount
pageInfo {
endCursor
hasNextPage
}
edges {
node {
firstName
lastName
}
}
}
}
`
const queryVars = cursor => { after: cursor, ...otherQueryVars }
// This works
const { loading, error, data, fetchMore } = useQuery(
QUERY, { variables: queryVars( ... ) }
)
// This doesn't work
const client = useApolloClient()
const fetchPages = async () => {
const { data } = await client.query( QUERY, { variables: queryVars( ... ) } )
}
...
}
Any idea what's going on here? The error message is a little vague, but I'm assuming it means that client.query() expects a DocumentNode as its first parameter, and the return type of gql is any...but then again, if this were true, I would expect useQuery to fail too, since it also expects the query to be a DocumentNode.
Welp, turns out the syntax is not the same. client.query() expects a sole QueryOptions parameter, whereas useQuery can take the query as the first parameter, and an optional QueryOptions second parameter.
I am trying to write a seed file for users and profiles with a one to one relationship and currently getting an "error: relation 'user_profiles' does not exist". From digging around, it seems like Adonis will assume this as a pivot table in the case of a many to many relationship. What I (think or intend to) have is a one to one relationship between users and profiles. Thanks in advance! Newbie to SQL and Adonis. As a side note, the user persists to the db, but there is no corresponding profile.
// My User Schema
class UserSchema extends Schema {
up () {
this.create('users', (table) => {
table.increments('id')
table.string('username', 80).notNullable().unique()
table.string('email', 254).notNullable().unique()
table.string('password', 60).notNullable()
// table.integer('profile_id').unsigned().references('id').inTable('userprofiles')
table.timestamps()
})
}
down () {
this.drop('users')
}
}
// My Profile Schema
class UserprofileSchema extends Schema {
up () {
this.create('userprofiles', (table) => {
table.increments()
table.string('first_name')
table.string('last_name')
// table.integer('user_id')
// .unsigned().references('id').inTable('users')
table.integer('user_id')
.unsigned()
.index('user_id')
table.foreign('user_id')
.references('users.id')
table.timestamps()
})
}
down () {
this.drop('userprofiles')
}
}
My User model includes the following relationship definition:
profile () {
return this.hasOne('App/Models/UserProfile')
}
// Seed script
class UserSeeder {
async run () {
try {
const user = await Factory.model('App/Models/User').create()
const userProfile = await Factory.model('App/Models/UserProfile').make()
userProfile.user_id = user.id
await user.profile().save(userProfile)
} catch (e) {
console.log('Error From Seeder: ', e);
}
}
}
Error code '42P01' and can post whole body if needed. Thanks!
On your Model userProfile, set table name as follows.
class User extends Model {
static get table () {
return 'userprofiles'
}
}
I have a specific kind of JSON which I need to code into a model for my Django problem. Problem is I have nested document in it or should I say object of objects and I don't know how to design the model in Pymodm or Mongoengine.
Here is the JSON schema on which I am working.
{
"something": "something",
"safasf": 5,
"key": {
"value1": ["dsd", "dd"],
"value2": {
"blah1": "blahvalue1",
"blah2": "blahvalue2"
}
}
}
I have already looked into the documentation and API References of both these ODMs. I could not find anything useful. At best they have fields.EmbeddedDocumentListField which stores list of documents/objects.
Your sample json is quite meaningless but this is an example of how you could model it with mongoengine
from mongoengine import *
class MyNestedDoc(EmbeddedDocument):
value1 = ListField(StringField())
value2 = DictField(StringField())
class MyDocument(Document):
something = StringField()
safasf = IntField()
key = EmbeddedDocumentField(MyNestedDoc)
nested_doc = MyNestedDoc(
value1=["dsd", "dd"],
value2={
"blah1": "blahvalue1",
"blah2": "blahvalue2"
}
)
doc = MyDocument(something="something", safasf=5, key=nested_doc)
doc.save()
This will save in Mongo an object with the following shape
{'_id': ObjectId('5d2d832c96d2914c2a32c1b3'),
'key': {
'value1': ['dsd', 'dd'],
'value2': {
'blah1': 'blahvalue1',
'blah2': 'blahvalue2'
}
},
'safasf': 5,
'something': 'something'
}
For some reason, I can't figure out how to simply find a specific piece of data in my SQLAlchemy database.
In the graphene-python documentation it simply does this query to match the id (which is a string):
book(id: "Qm9vazow") {
id
title
}
Now here's my Flask-Graphene-SQLAlchemy code for my BookSchema and I want to find a specific title instead of an ID:
class BookModel(db.Model):
__table__ = db.Model.metadata.tables['books_book']
# Schema Object
class BookSchema(SQLAlchemyObjectType):
class Meta:
model = BookModel
interfaces = (relay.Node, )
# Connection
class BookConnection(relay.Connection):
class Meta:
node = BookSchema
# GraphQL query
class Query(graphene.ObjectType):
node = relay.Node.Field()
allBooks = SQLAlchemyConnectionField(BookConnection)
schema = graphene.Schema(query=Query, types=[BookSchema])
When I run this query, everything is fine and returns 3 book titles:
{
"query": "{ allBooks(first: 3) { edges { node { title } } } }"
}
However, once I try to match a specific title, it stops working. For example:
# I tried all these queries, none worked
1. { allBooks(title: \"some book title\") { edges { node { title } } } }
2. { allBooks(title: \"some book title\") { title }
3. { allBooks(title: 'some book title') { edges { node { title } } } }
The error: "Unknown argument \"title\" on field \"allBooks\" of type \"Query\"."
I must be making a small error that I'm not seeing, but I can't figure it out. I've spent hours trying to figure this out.
Question: How can I match the title and have it return the object? What am I doing wrong?
Figured it out! See changes below.
class Query(graphene.ObjectType):
node = relay.Node.Field()
all_books = SQLAlchemyConnectionField(BookConnection)
# Added this
find_book = graphene.Field(BookSchema, title = graphene.String())
def resolve_find_book(self, info, title):
query = BookSchema.get_query(info)
return query.filter(BookModel.title == title).first()
And my GraphQL query looks like this:
{
"query": "{ findBook(title: \"some book title\") { title } }"
}
Hope this helps someone in the future!