Error while editing existing GSI on my scheme - amazon-dynamodb

I am using AppSync with DynamoDB and GraphQL API. My current scheme works as expected but when trying to edit existing GSI I am getting an error.
My current scheme looks like this:
type Item #model
#key(fields: ["id", "version"])
#key(name: "type-subtype", fields: ["type", "subtype"])
{
id: ID!
version: String!
type: String!
subtype: String!
}
I want to change GSI defined here to be:
#key(name: "version-type-subtype", fields: ["version", "type", "subtype"]
The error I am getting is Schema Creation Status is FAILED with details: Failed to parse schema document - ensure it's a valid SDL-formatted document.
Can someone help? Is there any constraint using sort key from primary index as hash in GSI that I am not aware of?
Thanks

Related

Is there a way to override AppSync auto generated input types when using Amplify?

Let's say we have the following graphql schema
type Customer
#model
#auth(
rules: [
{ allow: owner }
{ allow: groups, groups: ["Admin"] }
{ allow: public, provider: iam }
]
) {
id: ID! #primaryKey
owner: ID!
customer_last_name: String
}
When pushing above schema to AppSync via AWS Amplify, the following is created in the autogenerated graphql schema.
type Query {
getCustomer(id: ID!): Customer
#aws_iam
#aws_cognito_user_pools
listCustomers(
id: ID,
filter: ModelCustomerFilterInput,
limit: Int,
nextToken: String,
sortDirection: ModelSortDirection
): ModelCustomerConnection
#aws_iam
#aws_cognito_user_pools
}
Is it possible to pass and enforce a custom argument for the query input, such as
getCustomer(id: ID!, owner:ID!): Customer instead of the autogenerated getCustomer(id: ID!): Customer ?
This can be done by editing the autogenerated schema directly in the Appsync console, but in the case of a new Amplify push, the changes will be lost.
There can be only one Hash Key(aka Partition key or Primary Key) in dynamoDB. If you want multiple keys to be your Hash Key, you need to concatenate those keys into one Hash Key. The key pattern you want is called composite primary key.
For more information,
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.PrimaryKey
For creating a composite key with amplify graphql schema, please check details on this link. (Assuming you are using amplify graphql transformer v1)
https://docs.amplify.aws/cli-legacy/graphql-transformer/key/

How to create an Amplify Datastore many-to-many schema in version 3.7.3

I'm trying to set up a simple many-to-many relationship in Amplify Datastore using the new #hasMany directive. Unfortunately, there is no documentation other than "if you want to store additional properties on the join table, or if you have an existing join table, you can continue to use two #hasMany <=> #belongsTo relationships to facilitate a many-to-many relationship".
I want to have tables for warehouses and parts with a many-to-many relationship that tracks the in-stock quantity of a particular part at a particular warehouse:
type Part #model {
id: ID!
description: String!
inventories: [Inventory] #hasMany(indexName: "warehousesByPart", fields: ["id"])
}
type Warehouse #model {
id: ID!
description: String!
inventories: [Inventory] #hasMany(indexName: "partsByWarehouse", fields: ["id"])
}
type Inventory #model {
id: ID!
warehouseId: ID! #index(name: "partsByWarehouse", sortKeyFields: ["partId"])
partId: ID! #index(name: "warehousesByPart", sortKeyFields: ["warehouseId"])
part: Part! #belongsTo(fields: ["partId"])
warehouse: Warehouse! #belongsTo(fields: ["warehouseId"])
inStock: Int!
}
This is a front-end implementation only. Amplify CLI is the latest version (7.6.5). The error I get is
Error processing #hasMany directive on Warehouse.inventories, #index
directive with name partsByWarehouse was not found in connected model
Inventory
What am I doing wrong? Any help is much appreciated.
Changed the sequence of the types and added a primaryKey to the m2m table. The "Part" type has to be listed last in the schema, otherwise you will get an error. This is not documented anywhere as far as I can tell. I noticed that you will get errors when you flip the sequence even in the examples listed in aws docs. This is using amplify-modelgen. Also note much better documentation in the API (GraphQL) section of amplify's docs than in the Datastore section.
type Warehouse #model {
id: ID!
description: String!
inventories: [Inventory] #hasMany(indexName: "partsByWarehouse", fields: ["id"])
}
type Inventory #model {
partId: ID! #primaryKey(sortKeyFields: ["warehouseId"])
warehouseId: ID! #index(name: "partsByWarehouse")
part: Part! #belongsTo(fields: ["partId"])
warehouse: Warehouse! #belongsTo(fields: ["warehouseId"])
inStock: Int!
}
type Part #model {
id: ID!
description: String!
inventories: [Inventory] #hasMany(fields: ["id"])
}

serverless step functions: Getting error when passing more than one fields in the payload for lambda

Error: Invalid State Machine Definition: 'SCHEMA_VALIDATION_FAILED: The value for the field 'Date.$' must be a valid JSONPath at /States/Insert Data Dynamodb/Parameters' (Service: AWSStepFunctions; Status Code: 400; Error Code: InvalidDefinition;
below is the corresponding serverless.yaml code.
I tried wrapping the two parameters into encoded json string and passed it as single payload field and it resulted in the same error but when there is only one plain field in the payload this code deployed successfully
Any suggestions on how to pass two parameters?
service: service-name
frameworkVersion: '2'
provider:
name: aws
runtime: go1.x
lambdaHashingVersion: 20201221
stage: ${opt:stage, self:custom.defaultStage}
region: us-east-1
tags: ${self:custom.tagsObject}
logRetentionInDays: 1
timeout: 10
deploymentBucket: lambda-repository
memorySize: 128
tracing:
lambda: true
plugins:
- serverless-step-functions
configValidationMode: error
stepFunctions:
stateMachines:
sortData:
name: datasorting-dev
type: STANDARD
role: ${self:custom.datasorting.${self:provider.stage}.iam}
definition:
Comment: "Data Sort"
StartAt: Query Data
States:
Query Data:
Type: Task
Resource: arn:aws:states:::athena:startQueryExecution.sync
Parameters:
QueryString: >-
select * from table.data
WorkGroup: primary
ResultConfiguration:
OutputLocation: s3://output/location
Next: Insert Data Dynamodb
Insert Data Dynamodb:
Type: Task
Resource: arn:aws:states:::lambda:invoke
Parameters:
FunctionName: arn:aws:lambda:us-east-1:${account-id}:function:name
Payload:
OutputLocation.$: $.QueryExecution.ResultConfiguration.OutputLocation
Date.$: ${self:custom.dates.year}${self:custom.dates.month}${self:custom.dates.day}
End: true
Your Date.$ property has value of ${self:custom.dates.year}${self:custom.dates.month}${self:custom.dates.day}. Let's assume that:
const dates = {
"year": "2000",
"month": "01",
"day": "20"
}
The result will be Date.$: "20000120" which is not a valid JSON Path.
JSON Path needs to start with a $ sign and each level is divided by ..
Do you want to achieve something like this? $.2000.01.20?
As you see, the issue is not with passing 2 parameters but with wrong string JSON Path created by string interpolation for Date.$.
Some useful links:
https://github.com/json-path/JsonPath
https://docs.aws.amazon.com/step-functions/latest/dg/amazon-states-language-paths.html

DynamoDB Query with Global Secondary Index throws 'ValidationException: Query key condition not supported'

When trying to execute the query from the AppSync console in AWS, the following error keeps popping up, as seen in the logs of CloudWatch: 'ValidationException: Query key condition not supported'
I have tried changing the schema with different types and the Global Secondary Index where I swap the Partition Key and Sort Key. Also changing the code to scan rather then query works fine.
Using AWS-CDK I have setup an GraphQL API. For the DynamoDB table I want to use a Global Secondary Index. For that I have setup in my schema.graphql:
type ObjectName {
id: ID!
trackTimeStampUtc: Int!
channel: String!
...
}
with:
channel (String!) as Partition Key
trackTimeStampUtc (Int!) as Sort key
as so in Stack.ts:
const table = new ddb.Table(this, 'tableName', {
billingMode: ddb.BillingMode.PAY_PER_REQUEST,
timeToLiveAttribute: 'ttl',
partitionKey: {
name: 'id',
type: ddb.AttributeType.STRING,
},
});
table.addGlobalSecondaryIndex({
indexName: 'search-index',
partitionKey: {
name: 'channel',
type: ddb.AttributeType.STRING,
},
sortKey: {
name: 'trackTimeStampUtc',
type: ddb.AttributeType.NUMBER,
},
});
And in the Lambda handler with the function consuming the Params:
params: {
Index: 'search-index',
TableName: 'tableName',
KeyConditionExpression: '#ch = :channel and #ts between :start and :end',
ExpressionAttributeNames: {
'#ch': 'channel',
'#ts': 'trackTimeStampUtc'
},
ExpressionAttributeValues: {
':channel': 'test',
':start': 1610971398,
':end': 1611667818
}
}
Which is sent using await docClient.query(params).promise();
While I am sure I am doing something wrong I just can't seem to figure it out. Setting this up using .scan with some slight adjustment works fine, but having a GSI would be better. Please can anyone help?
Update 27-01 11:52:
I realize that the combination of Partition Key and Sort Key might not be the most efficient for the purpose it serves, regardless I wouldn't have any other combination work anyway. So getting this to work, for me, is understanding how it should work.
Update 29-01 15:18:
The issue is solved. Turned out I had Index in the Params for refering to the index name, instead of IndexName. Changed that fixed the issue and the query worked. Thank you again Peter.

Elasticsearch with symfony - Error populate command softdeletable entity

I use the symfony bundle Foselasticabundle and i am facing a problem.
I have an entity (B) which can be deleted via gedmo softdeleteable.
I created the mapping, via the YAML file, and when I execute the following command fos:elastica:populate i get an error.
Entity of type 'App\Entity\B' for IDs id(XX) was not found
In fact, value was previously deleted in my database...
I would have liked him to insert an empty value in the field
Do you have a solution?
Thank you for your answers
fos_elastica.yaml
clients:
default: { url: '%env(ELASTICSEARCH_URL)%/' }
indexes:
app:
types:
A:
properties:
id: ~
name: ~
B:
type: object
id: ~
persistence:
driver: orm
model: App\Entity\A

Resources