You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
However, with the Client Datastore, the only text-related Value type is StringValue. How can I store a Text value? I was considering Blob, but that's actually its own, separate type in Datastore (according to the Entity Property Reference)
This is indeed a good question. In the com.google.datastore.v1.Value proto (on which we rely) I see no way of setting a Text value. Setting a String value (using Value.Builder.setStringValue) longer than 1500 bytes fails with:
The value of property "bigString" is longer than 1500 bytes.
@eddavisson any insights on this? Is Text only available in AppEngine?
Here's something interesting: if I save a 3kb text string using the App Engine API as "Text", then I read the entity with that 3kb text string using the Client Datastore API, the Value type is StringValue.
Logically, I cannot turn around and save that entity, because a StringValue must be under 1500 bytes.
I don't see any issues with storing/retrieving Strings that are longer than 1500 bytes. I was able to insert 1MB (1,000,000 ascii characters) just fine. You just have to make sure the property is not indexed when saving. If indexing is turned on, you are limited to 1500 bytes. When I tried to do 1024 * 1024 bytes, I did hit the max limit with the below Exception:
The value of property "name" is longer than 1048487 bytes.
Check out the limits in the official documentation:
@sai-pullabhotla, running the following code throws a DatastoreException "The value of property "bork" is longer than 1500 bytes."
longString is ~11K
val datastore = DatastoreOptions.defaultInstance().service()
val longString = IOUtils.getResource("signature")
val keyFactory = datastore.newKeyFactory().kind("Test").namespace("4998Test")
val entity = FullEntity.builder(keyFactory.newKey()).set("bork", longString).build()
// or val entity = FullEntity.builder(keyFactory.newKey()).set("bork", StringValue(longString)).build()
datastore.put(entity)
It looks like, by default, all properties are indexed. How can I "unindex" a property using the Datastore Client API? According to the docs (see BaseEntity.Builder), you can only set() properties, not whether or not they're indexed
Can you provide an example of a block of code that will save over 1500 bytes of text?
That's correct, by default all properties are indexed, unless you indicate otherwise. To exclude properties from indexes, you have to use the ValueBuilder. For String type, you would use the StringValue.Builder. Link to JavaDoc below:
Thanks @sai-pullabhotla , but with your solution it works in the sense that it ends up storing the value (as a String), but there is no way to force it to be a Text type, right? What if there is an appengine app reading these entities and because of the code it uses it will be mandatory that the property is indeed a Text?
@afornie - it is just a terminology difference between the AppEngine and google-cloud APIs. From the Datastore server point of view, String/Text are same. Strings with more than 1500 byes cannot be indexed. So, you should be able to access the data fine from all APIs.
@sai-pullabhotla Unfortunately that's not true... they are NOT the same type when read through the AppEngine API.
When reading BLOBs or Text values written through the Cloud Datastore API it will depend on the size of the value written how they will appear in AppEngine. If they're no larger than 1500 bytes they will appear as ShortBlob (which isn't a sub-class of Blob) and String respectively and as Blob and Text if they're larger.
There seems to be no way to force Cloud Datastore API writing the expected type, hence you can't share the same datastore instance without modifying the AppEngine code base first to take care of the unexpected return types.
Why was this closed? It appears to still be an issue in the latest version of the Python client library. The workaround mentioned above is not sufficient because subsequently exporting those entities (which previously had a TextProperty field and now have a StringProperty field in its place) breaks the BigQuery schema when importing said exports.
Activity
mziccard commentedon Oct 19, 2016
Hi @mitchhentges, welcome back :)
This is indeed a good question. In the
com.google.datastore.v1.Valueproto (on which we rely) I see no way of setting aTextvalue. Setting aStringvalue (usingValue.Builder.setStringValue) longer than 1500 bytes fails with:@eddavisson any insights on this? Is
Textonly available in AppEngine?mitchhentges commentedon Oct 19, 2016
Here's something interesting: if I save a 3kb text string using the App Engine API as "Text", then I read the entity with that 3kb text string using the Client Datastore API, the
Valuetype isStringValue.Logically, I cannot turn around and save that entity, because a
StringValuemust be under 1500 bytes.sai-pullabhotla commentedon Oct 19, 2016
I don't see any issues with storing/retrieving Strings that are longer than 1500 bytes. I was able to insert 1MB (1,000,000 ascii characters) just fine. You just have to make sure the property is not indexed when saving. If indexing is turned on, you are limited to 1500 bytes. When I tried to do 1024 * 1024 bytes, I did hit the max limit with the below Exception:
The value of property "name" is longer than 1048487 bytes.
Check out the limits in the official documentation:
https://cloud.google.com/datastore/docs/concepts/limits
mitchhentges commentedon Oct 19, 2016
@sai-pullabhotla, running the following code throws a
DatastoreException"The value of property "bork" is longer than 1500 bytes."longStringis ~11KBaseEntity.Builder), you can onlyset()properties, not whether or not they're indexed1500bytes of text?sai-pullabhotla commentedon Oct 19, 2016
@mitchhentges,
That's correct, by default all properties are indexed, unless you indicate otherwise. To exclude properties from indexes, you have to use the ValueBuilder. For String type, you would use the StringValue.Builder. Link to JavaDoc below:
http://googlecloudplatform.github.io/google-cloud-java/0.4.0/apidocs/com/google/cloud/datastore/StringValue.Builder.html
Use the excludeFromIndexes(true).
Example -
entityBuilder.set("propertyName", StringValue.builder(hugeString).excludeFromIndexes(true).build());mitchhentges commentedon Oct 19, 2016
Thanks champ!
afornie commentedon Aug 17, 2017
Thanks @sai-pullabhotla , but with your solution it works in the sense that it ends up storing the value (as a String), but there is no way to force it to be a Text type, right? What if there is an appengine app reading these entities and because of the code it uses it will be mandatory that the property is indeed a Text?
sai-pullabhotla commentedon Aug 17, 2017
@afornie - it is just a terminology difference between the AppEngine and google-cloud APIs. From the Datastore server point of view, String/Text are same. Strings with more than 1500 byes cannot be indexed. So, you should be able to access the data fine from all APIs.
wguerlich commentedon Oct 10, 2017
@sai-pullabhotla Unfortunately that's not true... they are NOT the same type when read through the AppEngine API.
When reading BLOBs or Text values written through the Cloud Datastore API it will depend on the size of the value written how they will appear in AppEngine. If they're no larger than 1500 bytes they will appear as ShortBlob (which isn't a sub-class of Blob) and String respectively and as Blob and Text if they're larger.
There seems to be no way to force Cloud Datastore API writing the expected type, hence you can't share the same datastore instance without modifying the AppEngine code base first to take care of the unexpected return types.
leewisestamp commentedon Feb 20, 2022
Why was this closed? It appears to still be an issue in the latest version of the Python client library. The workaround mentioned above is not sufficient because subsequently exporting those entities (which previously had a TextProperty field and now have a StringProperty field in its place) breaks the BigQuery schema when importing said exports.
chore(samples): Add BatchGetEffectiveIamPolicy code samples (#1325)
AlecBruns commentedon Jan 3, 2023
Has there been any update on this? We are running into a similar issue with no ability to save fields as a 'Text' type
meltsufin commentedon Jan 3, 2023
There Datastore client library is not maintained in this repository. Please direct your questions here: https://github.com/googleapis/java-datastore.
chore(deps): update dependency com.google.cloud:google-cloud-logging …
build(deps): update dependency org.sonatype.plugins:nexus-staging-mav…
feat: Java datastore gapic upgrade (#1824)
chore(deps): update dependency com.google.cloud:google-cloud-logging …
feat: Java datastore gapic upgrade (#1824)
deps: update dependency com.google.cloud:google-cloud-spanner-bom to …
chore(main): release 2.11.9 (googleapis#1327)
deps: update dependency com.google.apis:google-api-services-storage t…
chore(main): release 0.127.9 (#1327)
deps: update dependency com.google.apis:google-api-services-storage t…
chore(main): release 0.127.9 (#1327)
chore(main): release 2.10.1 (googleapis#1325)
feat: Support Cloud Bigtable Changestream (googleapis#1569)