Closed thomasklaush closed 2 years ago
@thomasklaush do you mind providing a copy of your graphql schema here so we can reproduce this (and potentially advise a workaround)?
Workaround is to use 5.0.0 :-)
Sorry no other workaround currently
Query:
final List<ActivityEntry> activityEntries = await Amplify.DataStore.query(
ActivityEntry.classType,
where: ActivityEntry.ACTIVITYTYPE.eq(
ActivityType.KUBIKOS_ACTIVITY,
),
);
activityEntries.forEach((element) async {
final List<ActivityStepEntry> activityStepEntries = await Amplify.DataStore.query(
ActivityStepEntry.classType,
where: ActivityEntry.ID.eq(element.id),
);
logger.wtf('Kubikos Activity: ${element.name} with ${activityStepEntries.length} entries and id ${element.id}');
});
Schema:
type UserStatusEntry @model @auth(rules: [{
allow: owner,
}]) {
id: ID!
cognitoUser: String
entryType: EntryType!
timestamp: String!
jsonEntry: String!
}
enum EntryType {
GENERAL_ATTRIBUTES
FINGER_STRENGTH_STATUS
MUSCLE_STRENGTH_STATUS
}
type UserStatusData @model @auth(rules: [{
allow: owner,
}]) {
id: ID!
nickname: String
weight: Float!
birthday: AWSDateTime!
}
type ActivityEntry @model @auth(rules: [{
allow: owner,
}]) {
id: ID!
activityType: ActivityType!
name: String!
timestamp: AWSDateTime!
trainingTime: Int!
activityStepEntries: [ActivityStepEntry] @hasMany(indexName: "byActivityEntry", fields: ["id"])
s3Key: String
}
enum ActivityType {
TRAINING_PLAN
KUBIKOS_ACTIVITY
KUBIKOS_FORCE_TEST
}
type ActivityStepEntry @model @auth(rules: [{
allow: owner,
}]) {
id: ID!
activityEntryID: ID @index(name: "byActivityEntry")
activityEntry: ActivityEntry @belongsTo(fields: ["activityEntryID"])
name: String!
text: String!
exerciseId: Int
weight: Int
numReps: Int
}
Hello @thomasklaush thanks for reporting this issue.
Nested query predicates are not well supported at this moment. It was working partially in Android but this behavior is not officially documented. v0.5.1 fixed an issue not being able to create sync expression on model id field. This fix may break the partial support of nested predicate in Android.
The recommended way is to make separate queries like the workaround that you are using. We have some improvements on the roadmap providing better experience related model association, including well supported nested predicate. Please feel free to follow the updates in this feature request, and please provide suggestions and use case sample if you have any.
Hi @HuiSF ,
I use the workaround with separate queries, like written on AWS.
final List<ActivityStepEntry> activityStepEntries = await Amplify.DataStore.query(
ActivityStepEntry.classType,
where: ActivityEntry.ID.eq(element.id),
);
It seems, that : where: ActivityEntry.ID.eq(element.id),
is not working since 5.0.1.
Ok @thomasklaush thanks for the follow up, I'll take a look.
Hi @thomasklaush Looking at your code snippet and the schema
final List<ActivityEntry> activityEntries = await Amplify.DataStore.query(
ActivityEntry.classType,
where: ActivityEntry.ACTIVITYTYPE.eq(
ActivityType.KUBIKOS_ACTIVITY,
),
);
activityEntries.forEach((element) async {
final List<ActivityStepEntry> activityStepEntries = await Amplify.DataStore.query(
ActivityStepEntry.classType,
where: ActivityEntry.ID.eq(element.id),
);
logger.wtf('Kubikos Activity: ${element.name} with ${activityStepEntries.length} entries and id ${element.id}');
});
You were trying to query all children ActivityStepEntry
records of parent ActivityEntry
correct? if so I think the query should be
final List<ActivityStepEntry> activityStepEntries = await Amplify.DataStore.query(
ActivityStepEntry.classType,
where: ActivityEntry.ACTIVITYENTRY.eq(element.id),
);
From my tests, query by id works normally with version 0.5.1. (when providing correct predicate values.)
Dear @HuiSF, this solution is not working at all
@HuiSF your hint was good, just one mistake.
This is working, thanks.
Strange is, that it was working until 5.0.1 but now breaks.
I followed the documentation.
final List<ActivityStepEntry> activityStepEntries = await Amplify.DataStore.query(
ActivityStepEntry.classType,
where: ActivityStepEntry.ACTIVITYENTRY.eq(activityEntry.id),
);
This is working, thanks.
Glad to hear @thomasklaush
Strange is, that it was working until 5.0.1 but now breaks.
It should've never worked, if there is no match on the model id filed with given value it always returns empty list, unless the value happened to match the id of ActivityStepEntry
model.
Also could you point me which documentation you are referring to?
@HuiSF maybe it's a misinterpretation, classical layer 8 issue.
I used [https://docs.amplify.aws/lib/datastore/relational/q/platform/flutter/#querying-relations]
List<Comment> comments = await Amplify.DataStore.query(Comment.classType,
where: Post.STATUS.eq(PostStatus.ACTIVE));
I just changed STATUS to ID, since there is the id stored and I have the Id from the parent.
Sounded logical for me :-)
And it worked!
Until now. Anyway, thanks, problem solved.
Thanks! I'll verify the document
Update
The nested query listed in documentation is supposed to work
List<Comment> comments = await Amplify.DataStore.query(Comment.classType,
where: Post.STATUS.eq(PostStatus.ACTIVE));
Tested this functionality with different versions
Causes
For test 1, it didn't work is iOS because of that below logic https://github.com/aws-amplify/amplify-flutter/blob/26509326680a4a9d9d3cf47746a8fb492ae6cf6f/packages/amplify_datastore/ios/Classes/types/query/QueryPredicateBuilder.swift#L22-L29 removes model name from model id field name which generates a wrong SQL command
select
"root"."id" as "id", "root"."created" as "created", "root"."createdAt" as "createdAt",
"root"."rating" as "rating", "root"."title" as "title", "root"."updatedAt" as "updatedAt",
"root"."blogID" as "blogID", "blog"."id" as "blog.id", "blog"."createdAt" as "blog.createdAt",
"blog"."name" as "blog.name", "blog"."updatedAt" as "blog.updatedAt"
from "Post" as "root"
left outer join "Blog" as "blog"
on "blog"."id" = "root"."blogID"
where 1 = 1
# "root"."id" should be "blog"."id" in order to return expected results
and "root"."id" = ?
For test 1, it worked in Android, because of that model field id is named as <modelName>.id
, which allows Android to generated correct SQL command.
For test 2, as we enforce the logic above, the query predicate stopped work in both iOS and Android.
Will keep investigation for a solution to fix this issue. In the meantime, please use the workaround to unblock dev works.
Closing this issue in favor of https://github.com/aws-amplify/amplify-flutter/issues/1449 which tracks the progress on better dev experience around model associations.
Description
Relational querie return a empty list List comments = await Amplify.DataStore.query(Comment.classType,
where: Post.STATUS.eq(PostStatus.ACTIVE));
Categories
Steps to Reproduce
5.0.0 Datastore is working
5.0.1 return an empty list
Screenshots
No response
Platforms
Android Device/Emulator API Level
No response
Environment
Dependencies
Device
Pixel 6 Pro
OS
Android 12
CLI Version
stable
Additional Context
No response