-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Compound primary keys #1129
Comments
This feature would be great is it still on the roadmap? If not are there any work arounds that could be used in the meantime to get composite keys? |
+1 |
How can I check status of this task? |
+1 |
+1 |
This would solve a problem I'm currently facing. Would be a great feature to have! |
It's been 6 months. What's status? |
+1 |
7 similar comments
+1 |
+1 |
+1 |
+1 |
+1 |
+1 |
+1 |
One workaround we've used as a way of getting around this limitation is to create an 'id' property which simply concatenates the different fields that you want to use in your composite key. This way you get the uniqueness integrity checks but you can still program against the proper abstractions (ie: foreign keys/objects that make up your composite key - especially useful for "link table" objects between your various entities. |
+1 |
2 similar comments
+1 |
+1 |
A workaround what I have been using is to create the unique id of combining two id's before assigning it to realm object eg. class Pet : Object {
dynamic var combinedPrimary : String = ""
override class func primaryKey() -> String? {
return "combinedPrimary"
}
} let combinedKey = "\(person.id)\(pet.id)"
pet.combinedPrimary = combinedKey |
@RealPunk yup I think that's the recommended workaround. It's probably why the team hasn't been prioritizing this very much - along with the fact that Realm doesn't really expose foreign keys in any way (I'm no expert here, just my experience with it). So unlike traditional ORMs where you want to keep foreign keys around on objects to link to them in Realm you link to the object instance directly and the backing ID/structure is hidden from the programming model. For readability/sanity purposes I'd recommend throwing an extra ":" separator in there so you can re-infer the original IDs if needed: ie: "(person.id):(pet.id)" |
+1 |
Or you know, instead of writing +1 just click that "Subscribe" button. |
@Dragas agreed. Also, just |
+1 // realm-java, this is what I used:
public class Foo extends RealmObject {
@PrimaryKey
private String primaryKey;
private long id;
private int type;
private String name;
// getter and setter
// local defined primary key
public void compoundPrimaryKey() {
if(!isManaged()) {
// only unmanaged objects needs compound key
this.primaryKey = String.format("[I:%d][T:%d]", this.id, this.type);
}
}
}
// using
Foo foo = gson.fromJson(json, Foo.class);
foo.compoundPrimaryKey();
realm.insertOrUpdate(foo);
// or
List<Foo> foos = gson.fromJson(json, new TypeToken<List<Foo>>(){}.getType());
for (Foo foo: foos) {
foo.compoundPrimaryKey();
}
realm.insertOrUpdate(foos); |
I am currently using something similar to the example by @HsiangLeekwok. But there are a couple of problems with that:
|
Are you sure? I don't think it needs to have a public mutator since 0.88.0. But I could be wrong. |
@Zhuinden I think you are right. I just tried with a simple test app where I didn't even generate a setter for the "compound primary key string". And was able to insert a new instance to the realm. I verified the obj by using this compound key to query for the obj and print it to logcat, and I also verified it with the realm browser. In my defense, the docs mentions "Standard setters and getters", and they are exposed as |
+1 |
2 similar comments
+1 |
+1 |
Any clean code to do this? The suggestions so far seem horrible or aren't even java |
@behelit the current solution is still to keep your own "compound" String key that is constructed by concatenating whatever fields you wanted it to be based on Once you create a managed object with a given primary key, you can't mutate its primary key though, so keep that in mind |
+18 |
+1 million |
+1 |
3 similar comments
+1 |
+1 |
+1 |
I am getting a list of object that I write to the realm that I would like to generate a compound key for. Do I have to loop over the list of incoming data and generate the compound key for each object? Or is there some method I can override or something to generate the primary key as it is being written to the realm? |
yes
no (exception being that you set the compound primary key in a not-no-arg-constructor that Realm doesn't use but you do) |
When you want to persist a json array directly into a realm database you CANNOT ".. just concatenate the values together into a String." On the whole REALM is a brilliant mobile database, seems a pity that there a few "potholes" that have existed for some time which seem (on the face of it) to be obviously in need of fixing. The other is an AUTO incrementing primary key. Sure you can work round these, but is that really an acceptable solution in the 21st Century? If Realm wants to be take seriously can then take the time to iron out these wrinkles? |
I mean it worked for me, I just had to use a stream JSON parser to do it (considering I was saving 15000 items at a time).
Auto-increment PKs aren't that useful in Realm because you don't need a PK/FK to do "joins" because the concept of "Joins" and "foreign keys" doesn't exist in Realm. They'd only be useful if you detach and then try to re-attach objects often, and the object is created locally. It's better if a backend manages the IDs and you just download them and insert as is, in which case you don't need to manage auto-increment on your client side. |
I am also in need of this, will use the workaround with string concatenation for now and just commenting in case someone has the capacity to implement it 😄 |
Realm should also support composite primary keys. Reusing the
@PrimaryKey
annotation should be relatively simple.Primary keys are currently implemented in the binding. This should be implemented at the core level: realm/realm-core#831
The text was updated successfully, but these errors were encountered: