I have created a form in my Google App Engine application for users to select items from a list, the specific details of which (ex. name, other properties) will then be pulled from a datastore table called Item and displayed in a table once the user submits the form.
I have a Python list that contains the keys for the entries selected, pulled from the form. I want to use this list to look-up entries in the datastore and return them in a way that I can pass to a Django template.
I have tried to follow advice on this forum to use GQL Queries, but all I get thus far are empty results, whether using fetch(), hardcoding the key values, trying to use some variation of WHERE Key IN :list or WHERE Key = :variable.
If you need code, let me know which parts would be helpful.
db.get(list_of_keys)
http://code.google.com/appengine/docs/python/datastore/functions.html
Related
I am working on a project using the gcloud cli tools. I am using Python + Flask for developing the application. My main reference points have been the Google Datastore documentation as well this How-to tutorial guide.
I have some entities in my Datastore and these entities have some properties. Entities are created in the application, with the Key set to the default Key (a.k.a incomplete key).
I am able to access the entities alright. And using projection, I can also access the properties of each entity. However, is there a way to only extract the Key from an entity? Example:
>>> print(list(user_query.fetch()))
[<Entity('User', 5097358505279488) {...}>]
This works alright when I want to access the properties. However, I cannot access the key 509... I have also tried:
>>> for user in user_query.fetch():
print(user.key)
...
>>> <Key('User', 5097358505279488), project=...>
While it returns the whole Key object, I couldn't find a way to extract only the key. I have scoured the documentation for a solution, but it hasn't returned anything so. I am wondering if this is even possible at this point.
It sounds like you are trying to get a projection of key.id. Unfortunately, this is not possible. You can do a keys-only query that returns the keys, then you can use a list comprehension to get the data you want, e.g. [key.id_or_name for key in key_only_query.fetch_page()]
You use this to get id
print(user.key.id)
You can call the .id property on a datastore entity to get the key as an integer value.
for user in user_query.fetch():
print(user.id)
I have a web application that accesses large amounts of JSON data.
I want to use a key value database for storing JSON data owned/shared by different users of the web application (not users of the database). Each user should only be able to access the records they own or share.
In a relational database, I would add a column Owner to the record table, or manage shared ownerships in a separate table, and check access on the application side (Python). For key value stores, two approaches come to mind.
User ID as part of the key
What if I use keys like USERID_RECORDID and then write code to check the USERID before accessing the record? Is that a good idea? It wouldn't work with records that are shared between users.
User ID as part of the value
I could store one or more USERIDs in the value data and check if the data contains the ID of the user trying to access the record. Performance is probably slower than having the user ID as part of the key, but shared ownerships are possible.
What are typical patterns to do what I am trying to do?
Both of the solutions you described have some limitations.
You point yourself that including the owner ID in the key does not solve the problem of shared data. However, this solution may be acceptable, if you add another key/value pair, containing the IDs of the contents shared with this user (key: userId:shared, value: [id1, id2, id3...]).
Your second proposal, in which you include the list of users who were granted access to a given content, is OK if and only if you application needs to make a query to retrieve the list of users who have access to a particular content. If your need is to list all contents a given user can access, this design will lead you to poor performances, as the K/V store will have to scan all records -and this type of database engine usually don't allow you to create an index to optimise this kind of request.
From a more general point of view, with NoSQL databases and especially Key/Value stores, the model has to be defined according to the requests to be made by the application. It may lead you to duplicate some information. The application has the responsibility of maintaining the consistency of the data.
By example, if you need to get all contents for a given user, whether this user is the owner of the content or these contents were shared with him, I suggest you to create a key for the user, containing the list of content Ids for that user, as I already said. But if your app also needs to get the list of users allowed to access a given content, you should add their IDs in a field of this content. This would result in something like :
key: contentID, value: { ..., [userId1, userID2...]}
When you remove the access to a given content for a user, your app (and not the datastore) have to remove the userId from the content value, and the contentId from the list of contents for this user.
This design may imply for your app to make multiple requests: by example one to get the list of userIDs allowed to access a given content, and one or more to get these user profiles. However, this should not really be a problem as K/V stores usually have very high performances.
I want to store some items using Django cache API. Are there are best practices to follow while naming the key. I know some people just give user name as the key. But I am going to cache various items in different views and having the same key every where is not feasible. I was thinking on may be giving a key with username+ 'some view specific' so that the key can be unique.
Does any one have any other good suggestions for generating keys?
Generation of keys can depend on what you are tying to achieve.
Is what the user is trying to access for that user only?
Is what the user is trying to access generic for all the users?
e.g.
let's say you are trying to access a url:
http://yourserver/endpoint/?filter1=value1&filter2=value2
In the above case, you can use the query params filter1=value1&filter2=value2 to create a cached key (by generating the md5 hash).
Considering the two options earlier, if the view should return some data specific to the user then you can also append the user id to create a unique key for the user.
Another example could be a url like this, where one is trying to access all the articles from source 1:
http://yourserver/source/1/articles/?filter1=value1&filter2=value2
In this case it might also be useful to append the cache key with the source id (so this uses the context data for the views in generating the keys).
I'm using boto to connect dynamodb in python. I'm not seeing any proper tutorials for querying dynamodb. " What i need is that i need to fetch the content of the table where given name is present in firstname or last name where first name and last name are the two fields using dynamodb "
DynamoDB's Query operation only allows you to specify the hash and range keys. Scan will let you provide other fields, but it isn't recommended for general application use. I'm not familiar with boto, but if you want to further filter your results, you'll have to query if you can, then post-process the results in your application. Otherwise, you'll have to scan, which would allow you to use the CONTAINS comparison on one field at a time. You can't check both fields at the same time because the name would have to be found in both fields, not just one. See the table entries called ScanFilter on the Scan page for more information on what's possible.
I created an app that lets users input products and compare them. I am at the point where i need to consider scaling and multiple users, and I want to only show users the items that they've created (instead of the entire db, which may be an option at some point, but for now each user has to create their own lists).
Is there a canned/preferred way of making all queries throughout an app only return entries with the "author" field set to a certain user, the logged in user? Or does every query have to be updated with "AND author..." type filter? Is this what namespaces are for?
I'm using Python on Google App Engine.
I would suggest looking into namespaces, it is exactly the type of use-case they are well suited for.
One note, if you want to be able to query users all users' products, you may be better off adding an owner property and using query filters. You can't currently query across namespaces -- only within a single namespace at one time.