django cache key naming - python

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).

Related

Is there a Redis-py function to get all secondary values

I want to create a simple registration using a redis database. For this the user should not be able to register with an existing username/email. Say I use the username as the primary key, how would I check if any secondary values include the email they're trying to sign up with.
I've tried iterating through all primary keys and getting all the values but this seems too slow, is there a faster way to do this?
Scanning the keyspace isn't a viable runtime strategy. You'll need to "index" the values that you search for - see https://redis.io/topics/indexes for more information.

How do you control user access to records in a key-value database?

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.

Is token possible to make duplication in django rest framework?

I tried to track the code in django rest framework.
I was researching the Token how to generate by DRF.
It's DRF repository from github about generating key:
def generate_key(self):
return binascii.hexlify(os.urandom(20)).decode()
I have a doubt. Is it possible to make duplication?
Actually, I don't know why it uses os.urandom and binascii.hexlify can generate unique key. Anyone can explain it?
That code doesn't generate unique keys, it generates random (or pseudo-random) keys that are large enough to have a very low probability of being a duplicate.
However, the value is used as the primary key of the model. In most (if not all) databases, primary keys are unique. So if it did happen to generate a duplicate, it would fail when it tried to commit. Although in Django's case it may just assume you were updating the existing record and change the user the token was assigned to. It's not something to reasonably worry about, the probability is too low.

Is there a function to check whether an ID you want to use for an entity is available?

I think I read something about a function appengine has that can tell whether an ID / key you want to use for an entity is available, or if there was a function to get an available ID to choose. App engine team said also that we should set the ID when the entity is created and not change it. But in practice we can just copy everything to a new entity with the new ID?
Thanks!
Update
I think the function I'm looking for is allocateIDs from the docs:
http://code.google.com/appengine/docs/python/datastore/functions.html
To reserve one or more IDs, use allocate_ids(). To check whether an ID is already taken, just construct a Key for it using Key.from_path(kind, id) and try to db.get() it. Also note that IDs for keys with a parent are taken from separate pools and are only unique among keys with the same parent.
On the page describing transactions, a use case is presented where the entity in question, a SalesAccount is updated, or if the account doesn't exist, it is created instead. The technique is to just try to load the entity with the given key; and if it returns nothing, create it. It's important to do this inside a transaction to avoid the situation where two users are both racing for the same key, and both see that it doesn't exist (and both try to create it).

Using Python list to query Google App Engine datastore

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

Categories

Resources