NeedIndexError in Google App Engine, despite indexes being served - python-2.7

I have uploaded my index.yaml file using the command line SDK:
Unfortunately I now have some of my entities indexed twice (but they are all serving):
But I am still getting a "Need Index Error" on running the page:
NeedIndexError: no matching index found. recommended index is:
- kind: RouteDetails
ancestor: yes
properties:
- name: RouteName
direction: desc
The suggested index for this query is:
- kind: RouteDetails
ancestor: yes
properties:
- name: RouteName
direction: desc
How can I get Google App Engine to recognise my entity's index?
And how do I delete the duplicates? (Do I need to?)

Datastore requires explicit indexes to be created for each query type when the query scans over more than one property or is an ancestor query. And kinds will certainly be indexed more than once if you have different query types.
For example:
SELECT * FROM RouteDetails
WHERE __key__ HAS ANCESTOR KEY(ParentKind, 'foo')
ORDER BY RouteName ASC
requires an ascending index.
- kind: RouteDetails
ancestor: yes
properties:
- name: RouteName
direction: asc
And
SELECT * FROM RouteDetails
WHERE __key__ HAS ANCESTOR KEY(ParentKind, 'foo')
ORDER BY RouteName DESC
requires a separate descending index.
- kind: RouteDetails
ancestor: yes
properties:
- name: RouteName
direction: desc
https://cloud.google.com/datastore/docs/concepts/indexes
In your case, it appears you are performing an ancestor query with a descending ORDER BY of the RouteName property and adding the suggested index to your index.yaml file should solve the problem for you.
As for the suspected "duplicates", which indexes need to exist depend on the specific queries your application performs.
But if you determine that you have extra unused indexes, the instructions for vacuuming indexes can be found here: https://cloud.google.com/datastore/docs/tools/indexconfig#Datastore_Deleting_unused_indexes

The index includes the order by direction - you can see the up arrows in the console view indicating all fields ascending.
The suggested index is a descending index on one of the properties.
Your 'duplicate' indexes have been introduced by the reason field, which you indexed as both capital r and lower case r, which are different named fields

Just in case anyone else stumbles across this question and is having a similar problem.
The reason it was looking for an index with ancestor: yes is that I was using the wrong query, and it should not have had an ancestor key in it at all.
Here is my new query:
class RouteDetails(ndb.Model):
"""Get list of routes from Datastore """
RouteName = ndb.StringProperty()
#classmethod
def query_routes(cls):
return cls.query().order(-cls.RouteName)
class RoutesPage(webapp2.RequestHandler):
def get(self):
adminLink = authenticate.get_adminlink()
authMessage = authenticate.get_authmessage()
self.output_routes(authMessage,adminLink)
def output_routes(self,authMessage,adminLink):
self.response.headers['Content-Type'] = 'text/html'
html = templates.base
html = html.replace('#title#', templates.routes_title)
html = html.replace('#authmessage#', authMessage)
html = html.replace('#adminlink#', adminLink)
self.response.out.write(html + '<ul>')
list_name = self.request.get('list_name')
#version_key = ndb.Key("List of routes", list_name or "*notitle*")
routes = RouteDetails.query_routes().fetch(20)
for route in routes:
self.response.out.write('<li>%s</li>' % route)
self.response.out.write('</ul>' + templates.footer)
I was using this page of the documentation, which doesn't tell you how to construct a query for a kind with no ancestor.
https://cloud.google.com/appengine/docs/standard/python/datastore/queries

Related

What is the contain method in Django rest_framework Filter

Let's say I have a database that looks like this:
{
name: 'We love Football',
type: 'Sports',
}
{
name: 'Let's play Football',
type: 'Sports'
}
{
name: 'Let's play Basketball',
type: 'Sports'
}
I need to implement something like this:
class GameAPIListView(ListAPIView):
serializer_class = GameSerializer
def get_queryset(self):
term = self.request.GET['term']
data = Game.objects.filter(name.contains(term))
return data
If I type "Fooball", the first two items will be returned, since they contain the token "Football". What is the correct way to do this? Thanks in advance.
You need to try with name__contains link. another thing is to search with icontains link for case insensitive search.
Also if you are using postgres database there are so many additional search features link
available in django.

No matching index found even Google Cloud show them

I am trying to execute the following query:
SELECT google_uid FROM User WHERE api_key = #api_key
But I get the error:
no matching index found. recommended index is:\n- kind: User\n
properties:\n - name: api_key\n - name: google_uid\n
Here is the index configuration from Google:
I uploaded it yesterday, so I am sure Google have had time to update it on their side.
Any idea how to solve it?
Thanks
The properties in the index are ordered. So you have an index of (google_uid, api_key), but you don't have an index of (api_key, google_uid). This query requires a composite index of (api_key, google_uid) .
You can see this if you run the querySELECT data_clicked from User where api_key = #api_key . That will work since you have an index where api_key is the first property.

Datastore: composite index not recognised

I've written a piece of code that adds and retrieves entities from the Datastore based on one filter (and order on the same property) - that worked fine. But when I tried adding filters for more properties, I got:
PreconditionFailed: 412 no matching index found. recommended index is:- kind: Temperature properties: - name: DeviceID - name: created
Eventually I figured out that I need to create index.yaml. Mine looks like this:
indexes:
- kind: Temperature
ancestor: no
properties:
- name: ID
- name: created
- name: Value
And it seems to be recognised, as the console shows:
that it has been updated
Yet when I run my code (specifically this part with two properties), it doesn't work (still getting the above-mentioned error) (the code is running on the Compute Engine).
query.add_filter('created', '>=', newStart)
query.add_filter('created', '<', newEnd)
query.add_filter('DeviceID', '=', devID)
query.order = ['created']
Trying to run the same query on the console produces
Your Datastore does not have the composite index (developer-supplied) required for this query.
error. Search showed one other person who had the same issue and he managed to fix it by changing the order of the properties in the index.yaml, but that is not helping in my case. Has anybody encountered a similar problem or could help me with the solution?
You'll need to create the exact index suggested in the error message:
- kind: Temperature
ancestor: no
properties:
- name: DeviceID
- name: created
Specifically, the first property in the index needs to be DeviceID instead of ID and the last property in the index needs to be the one you're using in the inequality filter (so you can't have Value as the last property in the index).

Paginated array would not show

I'm rather new to Ruby on Rails so would appreciate some help
Roles have Users in my application.
When showing a role I would like to render a paginated list of user names (and as a further refactor - links to users).
Currently my HAML template is as follows
...
%ul.assigned-users
- if #role.users.present?
- names = #role.users.collect {|u| u.name}
- links = Kaminari.paginate_array(names).page(params[:page]).per(20)
= paginate links
- else
%p No users have this role assigned
...
Rendering it gives me the pagination links BUT no names.
Kaminari's paginate_array method does not show the values in the array.
The best way to do so is get the query paginated from the database. Kaminari.paginate_array in your code takes in the whole array of users from the database and then paginates it which is highly inefficient and memory consuming.
You need to add the logic to the controller. If you paginate the #role.users query, it is generated with LIMIT which is the value you assign in the per method and OFFSET which equals to (params[:page] - 1) * per. This gets only the number of records you need from the database.
In your controller app/controllers/roles_controller.rb
class ConversationsController < ApplicationController
def show
#role = Role.find params[:id]
#users = #role.users.page(params[:page]).per(20)
end
end
In your view app/views/roles/show.html.haml
%ul.assigned-users
- if #users.present?
- #users.each do |u|
%li=u.name
= paginate #users
- else
%p No users have this role assigned

How to create a unique constraints in YML in Doctrine2?

I Want to create a unique constraints on two attributs. The YML configuration with Doctrine2 isn't well documented. So I try to traduct the XML in YML. What's wrong with this code?
unique-constraints:
name: event_user
columns:
event_id: ~
user_id: ~
Thanks in advance.
Finally I managed to create it by this code:
uniqueConstraints:
event_user_idx:
columns: event_id,user_id
But Thank Reuven for your answer.
You should try that:
uniqueConstraints:
event_user:
columns:
- event_id
- user_id
I don't know if this part of the documentation has been added recently or not, but here is what it says:
# ECommerceProduct.orm.yml
ECommerceProduct:
type: entity
fields:
# definition of some fields
uniqueConstraints:
search_idx:
columns: [ name, email ]