I have a following model in the Google appengine app.
class TestModel(db.Model):
names = db.StringListProperty(required=False)
So, I want to get entries which has not empty in names property. I tried like this.
TestModel.all().filter('names !=', [])
But it raises the exception: BadValueError: Filtering on lists is not supported
How can I filter it? or Should I check one by one like following?
for entry in TestModel.all():
if len(entry.names) > 0:
result.append(entry)
Try this:
TestModel.all().filter('names >=', None)
This will give you every entity with at least one value set for names, i.e. every value in the index.
Related
I've finally started to understand a lot of info regarding FireStore, but I'm wondering if I can get some assistance.
If I had a setup similar to or like this:
races
Android
name: Android
size: medium
stats <---- this is the map
str: 10
sex: 12.... (more values)
How would I parse this? I am looking to make specific TextViews apply values found in the database so that I can simply update the database and my app will populate those values so that hard coding and code updating won't be nearly as troublesome in the future.
I currently use something like this:
val androidRef = db.collection("races").document("Android")
androidRef.get().addOnSuccessListener { document ->
if (document != null) {
oneOfTheTextViews.text = document.getString("str")
} else {
}
The issue is currently I can only seem to access from collection (races) / document (android) / then a single field (I have "str" set as a single field, not part of a map or array)
What would the best practice be to do this? Should I not nest them at all? And if I can reference said nesting/mapping/array, what functions need to be called? (To be clear, I am not asking only whether or not it is possible - the reference guides and documents allude to such - but what property/class/method/etc needs to be called in order to access only one of those values or point to one of those values?).
Second question: Is there a way to get a list of document names? If I have several races, and simply want to make a spinner or recycler view based on document names as part of a collection, can I read that to the app?
What would the best practice be to do this?
If you want to get the value of your str property which is nested within your stats map, please change the following line of code:
oneOfTheTextViews.text = document.getString("str")
to
oneOfTheTextViews.text = document.getString("stats.str")
If your str property is a number and not a String, then instead of the above line of code please use this one:
oneOfTheTextViews.text = document.getLong("stats.str")
Should I not nest them at all?
No, you can nest as many properties as you want within a Map.
Is there a way to get a list of document names?
Yes, simply iterate the collection and get the document ids using getId() function.
On my application i have to search for an alphanumeric id which return one or more rows of data. On each of these rows a link is present i have to click on the first link.
Unfortunately it doesn't have any unique properties so i cannot add it to the OR. Instead i used descriptive programming something like below
'returns false
page.Link("class:=ng-binding","innertext:=AplhaID","html tag:=A").Exist
QTP fails to identify the object with the above code. So Instead of this i tried using Description object something like the below code
Set oDesc = Description.Object
oDesc("class").Value = "ng-binding"
oDesc("html tag").Value = "A"
oDesc("innertext").Value = "AplhaID"
Set lnk = page.ChildObjects(oDesc)
'gives me 2 which is correct. There are two links
msgbox lnk.Count
'highlights the correct link
lnk(0).Highlight
I do not know what could be causing this behavior. I thought is could be because multiple links match the description but I perform this search for multiple ids and eventhough multiple rows are returned the descriptive programming code is able to identify the correct row and proceed.
I looked at QTP descriptive programming issue but my link's property values do not have special characters.
In order to use Descriptive string method, ensure that you have only one object matching the given properties.
Below statement might fail if there are more than 1 object with the given properties.
page.Link("class:=ng-binding","innertext:=AplhaID","html tag:=A").Exist
So , you need to make the statement to find an object uniquely. Try this. It will work!
page.Link("class:=ng-binding","innertext:=AplhaID","html tag:=A", "index:=0").Exist
Can I filter by.repeater('object in array') so it returns just objects with a specific value in Protractor?
E.g. something like
var filteredElements = element.all(by.repeater('object in array')).column('object.type').value('car'));
Is something like this possible without creating additional loops (and without creating new promises)?
These elements doesn't have any unique identifier? If they have you can do a cssSelector searching for that specific identifier (id, class or any other attributes..)
If they don't have ny unique identifier, the best way to do that is change you FE application to add the class "car" to each element that you want to have, and then, have a selector that retrieves all the element with class "car".
I have this code to find all the nodes where property branches is empty.
nobranches=TreeNode.all()
for tree in nobranches:
if tree.branches==[]:
I wanted to find a better, more efficient way to do this. A meathod where I don't have to retrieve all the TreeNodes. I have tried TreeNode.all().filter(branches=[]) but this gives me a message, "BadValueError('Filtering on lists is not supported'" . How can I do something like TreeNode.gql('WHERE branches=:1', []).fetch(100). I tried this, but I get a "BadValueError: May not use the empty list as a property value; property is []". Is there any other efficient way?
BTW, Here is what TreeNode looks Like
class TreeNode(db.Model):
name = db.StringProperty()
branches =db.ListProperty(db.Key)
You can't do this with a filter: as Saxon says, there's no index row matching what you want to retrieve, and so no way to retrieve it.
One simple alternative is to store another property that contains the number of elements in the list, and filter on that. aetycoon is a library that contains computed properties that may help with that:
class TreeNode(db.Model):
name = db.StringProperty()
branches = db.ListProperty(db.Key)
branch_count = aetycoon.DerivedProperty(lambda self: len(self.branches))
The documentation on how indexes are stored says:
For multi-valued properties, such as ListProperty and StringListProperty, each value has its own index row, so using multi-valued properties does result in more indexing overhead.
So for each item in your list property, there is a row in the index.
My expectation would be that if there are no items in the list property, then there would be no rows in the index. So it wouldn't be possible to use the index to retrieve entities with an empty list.
One solution would be to add another property (eg hasbranches = db.BooleanProperty()), which you maintain when you add or remove branches. Then you will be able to filter for hasbranches = False.
I need to filter entities based on one of their ListProperties having a certain element present. So kind of like:
entities.filter('listProp IN ',element) except where listProp and element are reversed if you see what I mean.
Anyone know how to filter like this?
If I understand you correctly, you want to find all entities which have that particular element present. You should be able to use: entities.filter('listProp =', element)
Look at: http://code.google.com/appengine/docs/python/datastore/typesandpropertyclasses.html#ListProperty
It says, "list_property = value tests if the value appears anywhere in the list".
Ok so it turns out the IN equality clause takes care of this case for lists automatically.
As in it does a for ... each on the list of elements to be searched for and if any one of them is present in the ListProperty for each entity it will return that entity.