Updating an object with Realm without a Primary Key - react-native

In my React-Native app, I need to update some objects but I can't do like the tutorial :
realm.write(() => {
// Create a book object
realm.create('Book', {id: 1, title: 'Recipes', price: 35});
// Update book with new price keyed off the id
realm.create('Book', {id: 1, price: 55}, true);
});
Because my objects don't have a primary key (and i don't want them to have primary key)
There is my try :
this.state.realm.write(() => {
this.state.realm.create('Bills', {type: this.state.billType,
creditor: this.state.billCreditor, month: this.state.billMonth,
year: this.state.billYear, price: this.state.billPrice}, true);
});
But this try obviously create an another object ^^
Is someone have an idea for my problem please? Thanks for all =)

Finally, I used UUID as Primary key ^^"
https://www.npmjs.com/package/react-native-uuid

Currently Realm doesn't support updating objects without primary keys. See this GitHub issue.
If you really want to achieve this, you will have to delete the object from Realm and then adding it with the updated values.
However, I wouldn't recommend this method. Creating a primary key in most cases is the optimal solution, so you should reconsider using it. The built in update method will in most cases have a better performance than any method you could write without using primary keys.

Related

How to create a new table with partition key and sort key with AWS-Amplify?

I need to add a sort key and partition key to an existing dynamo db table... I created a new table with a partition key and sort key manual. But when I try to get one separate from the table it gives an error called "The provided key element does not match the schema". For that reason, I want to create a new table with a partition key and sort key. How can I edit my graphql schema and do a amplify push to create a new table? Please help... following is my graphql schema
type Idea #model
{
id: ID!
title: String!
userName: String
category: String!
status:String
OtherCategory: String
description: String
subCategory: String
createdAt: AWSDateTime
updatedAt: AWSDateTime
comments: [Comment] #connection(name: "IdeaComments")
}
Take a look at the new #key directive that was added to Amplify's GraphQL Transformer: https://aws-amplify.github.io/docs/cli/graphql#key

Mobx-state-tree create form with types.identifier field on model

I've started using mobx-state-tree recently and I have a practical question.
I have a model that has a types.identifier field, this is the database id of the resource and when I query for existing stuff it gets populated.
When I am creating a new instance, though, following the example that Michel has on egghead, I need to pass an initial id to my MyModel.create() on initial state, however, this ID will only be known once I post the creation to the API and get the resulting created resource.
I have searched around for a simple crud example using mobx-state-tree but couldn't find one (suggestions?).
What is the best practice here? Should I do a `MyModel.create({ id: 'foobar' }) and weed it out when I post to the API (and update the instance once I get the response from the API)?
This is a limitation of mobx-state-tree's current design. Identifiers are immutable.
One strategy I've seen to get around this issue is to store your persistence layer's id in a separate field from your types.identifier field. You would then use a library like uuid to generate the types.identifier value:
import { v4 } from "node-uuid"
const Box = types
.model("Box", {
id: types.identifier,
name: "hal",
x: 0,
y: 0
})
const box = Box.create({ 'hal', 10, 10, id: v4() })

"Cannot return null for non-nullable type: 'Person' within parent 'Messages' (/getMessages/sendBy)" in GraphQL SDL( aws appsync)

Iam new to graphql.Iam implementing a react-native app using aws appsync.Following is the code i have written in schema
type Messages {
id: ID!
createdAt: String!
updateAt: String!
text: String!
sendBy: Person!
#relation(name: "UserMessages")}
type Person {
id: ID!
createdAt: String!
updateAt: String!
name: String!
messages: [Messages!]!
#relation(name: "UserMessages")}
When i tried to query the sendBy value it is giving me an error saying
query getMessages{
getMessages(id : "a0546b5d-1faf-444c-b243-fab5e1f47d2d") {
id
text
sendBy {
name
}
}
}
{
"data": {
"getMessages": null
},
"errors": [
{
"path": [
"getMessages",
"sendBy"
],
"locations": null,
"message": "Cannot return null for non-nullable type: 'Person' within parent 'Messages' (/getMessages/sendBy)"
}
]
}
Am not understanding that error please help me.Thanks!! in Advance
This might sound silly, but still, developers do this kind of mistakes so did I. In subscription, the client can retrieve only those fields which are outputted in the mutation query. For example, if your mutation query looks like this:
mutation newMessage {
addMessage(input:{
field_1: "",
field_2: "",
field_n: "",
}){
field_1,
field_2
}
}
In the above mutation since we are outputting only field_1 & field_2. A client can retrieve the only subset of these fields.
So if in the schema, for a subscription if you have defined field_3 as required(!), and since you are not outputting field_3 in the above mutation, this will throw the error saying Cannot return null for non-nullable type: field_3.
Looks like the path [getMessages, sendBy] is resolving to a null value, and your schema definition (sendBy: Person!) says sendBy field cannot resolve to null. Please check if a resolver is attached to the field sendBy in type Messages.
If there is a resolver attached, please enable CloudWatch logs for this API (This can be done on the Settings page in Console, select ALL option). You should be able to check what the resolved Request/Response mapping was for the path [getMessages, 0, sendBy].
I encountered a similar issue while working on my setup with CloudFormation. In my particular situation I didn't configure the Projection correctly for the Global Secondary Indexes. Since the attributes weren't projected into the index, I was getting an ID in the response but null for all other values. Updating the ProjectionType to 'ALL' resolved my issue. Not to say that is the "correct" setting but for my particular implementation it was needed.
More on Global Secondary Index Projection for CloudFormation can be found here: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dynamodb-projectionobject.html
Attributes that are copied (projected) from the source table into the index. These attributes are additions to the primary key attributes and index key attributes, which are automatically projected.
I had a similar issue.
What happened to me was a problem with an update resolver. I was updating a field that was used as GSI (Global Secondary Index). But I was not updating the GSI, so when query by GSI the index exists but the key for that attribute had changed.
If you are using Dynamo DB, you can start debugging there. You can check the item and see if you have any reference to the primary key or the indexes.
I had a similar issue.
for me the problem was lying with the return type of the schema . As i was doing a query with PK on dynamodb table ..it was returning a list of items or data you can say . but in my schema i had a schema define as a singular struct format .
Error was resolved when i just made the return type in schema as list of items .
like
type mySchema {
[ID]
}
instead of
type mySchema
{
id : ID!
name : String!
details : String!
}
This error is thrown for multiple reasons . so your reason could be else but still i just posted one of the scenarios.

Updating entities with primary key and alternate composite key

I have a series of metric snapshot data I am uploading into my database on a daily basis. I take the input and check to determine if it is already in the database, and if it's not I add it. Each record uses a composite key made up of three columns, and also has a primary key.
I have since tried to add logic so that I can optionally force an update on records that already exist in the database, in addition to adding those that don't yet exist. I run into an error though preventing me, saying that there is already an object with the specified key being tracked.
The instance of entity type 'MembershipSnapshot' cannot be tracked
because another instance of this type with the same key is already
being tracked. When adding new entities, for most key types a unique
temporary key value will be created if no key is set (i.e. if the key
property is assigned the default value for its type). If you are
explicitly setting key values for new entities, ensure they do not
collide with existing entities or temporary values generated for other
new entities. When attaching existing entities, ensure that only one
entity instance with a given key value is attached to the context.
Here's a snippet of my code.
// Get the composite keys from the supplied list
var snapshotKeys = snapshots.Select(s => new { s.MembershipYear, s.DataDate, s.Aggregate }).ToArray();
// Find which records already exist in the database, pulling their composite keys
var snapshotsInDb = platformContext.MembershipSnapshots.Where(s => snapshotKeys.Contains(new { s.MembershipYear, s.DataDate, s.Aggregate }))
.Select(s => new { s.MembershipYear, s.DataDate, s.Aggregate }).ToArray();
// And filter them out, so we remain with the ones that don't yet exist
var addSnapshots = snapshots.Where(s => !snapshotsInDb.Contains(new { s.MembershipYear, s.DataDate, s.Aggregate }))
.ToList();
// Update the ones that already exist
var updateSnapshots = snapshots.Where(s => snapshotsInDb.Contains(new { s.MembershipYear, s.DataDate, s.Aggregate }))
.ToList();
platformContext.MembershipSnapshots.AddRange(addSnapshots);
platformContext.MembershipSnapshots.UpdateRange(updateSnapshots);
platformContext.SaveChanges();
How do I go about accomplishing this task?
I don't have a compelling reason why I have an auto-increment primary key, other than perhaps whatever performance issues it might give SQL internally?
EDIT: The way I've currently solved this issue is my removing my surrogate key, which I'm not using at all for anything. Still, it would be nice to know a workaround without having to remove this as a surrogate key could come in handy in the future.

Check availability of foreign key value in the foreign table

Say I have 2 tables, A and B.
B has a foreign key from A.
Whenever I insert data to table B, I should check availability of foreign key in the table A.
Is there any way to do this process instead of doing it manually ?
I have googled it by myself, and found that CExistValidator is probably what I want.
But I didn't find any comprehensive example for use of that validator.
If CExistValidator is the answer, can you give me some example ?
Thanks.
Let's say you have a class Category which has many Pages. You want to ensure that Page belongs to some existing Category:
class Page {
//...
public function rules()
{
return array(
array('category_id', 'exist', 'className' => 'Category', 'attributeName' => 'id'),
);
}
}