GAE DataStore: query a existing by user_id field - python

I have saved the user_id() field and now I want to query the datastore for that user.
How would I go about accomplishing that?
#Something like
user = db.Query(MyUser).filter('user.user_id() = ', 1234).fetch(limit=1)
Thanks

You should create a separate string property to store the user ID, then query for that. The UserProperty class is full of traps and is best avoided.

if what you are searching for is the actual entity Id then you can query for it with the get_by_id method
user = MyUser.get_by_id(1234)
note that if you create it with a parent the you need to pass that to the get_by_id() function too.
user = MyUser.get_by_id(1234, parent=parent)
docs:
https://developers.google.com/appengine/docs/python/datastore/modelclass#Model_get_by_id

Related

Querying nested KeyProperties

I have the following models:
class Company(ndb.Model):
name = ndb.StringProperty(indexed=False)
# some other fields
class User(polymodel.PolyModel):
company = ndb.KeyProperty(kind=Company)
# some other fields
class Object(ndb.Model):
user = ndb.KeyProperty(kind=User)
# some other fields
Now I have a user and I want to query Objects that are associated with other Users in the same company like this:
Object.query(Object.user.company == user.company)
Of course, this doesn't work, since Object.user is a key and I cannot access anything beyond that.
Is there any way to do it? I only need the company key, I was thinking on a ComputedProperty but I'm not sure if it's the best solution. Also, it would be better to query based on any field in company.
You need to denormalize and store redundant information, as the datastore doesn't support joins.
For instance given your models above, a user can only be a member of one company, if you really need to search all objects whose user is a member of a particular company then store the company key in the Object.
Use a computed property if that works best for you.
Alternately use a factory that always takes the User as a argument and construct Object that way.

How to get child model related data in parent model query

I have two models:
class BusinessCard(models.Model):
name = models.CharField(_("name"),null=True,max_length=50)
class Contacts(models.Model):
businesscard_id = models.OneToOneField(BusinessCard,null=True,blank=True,related_name='contact_detail',db_column="businesscard_id")
bcard_json_data = JsonField(null=True)
I just want access contacts model data using business card model:
target_bacard=BusinessCard.objects.filter(id=target_bacard_id).select_related()
When we access the target_bacard.contact_detail it gives key errors.
How can I get the contacts data using target_bacard queryset.
use get() instead of filter() like:
target_bacard = BusinessCard.objects.get(id=target_bacard_id)
target_bacard.contact_detail
If you want to access the Contacts instance that is in the 1-to-1 relationship with a BusinessCard instance bacard, use the related name you specified in Contacts:
contact = bacard.contact_detail
Also, you have some misleading names: Contacts should rather be Contact since an instance of this model represents only one contact. And its field businesscard_id would better be named businesscard (note that the table column will be called businesscard_id at the database level automatically in that case and store the id of the related businesssscard) because in the ORM you get a BusinessCard model instance when you access it, and not just its id.
You have not passed related model (field) argument to select_related()
target_bacard=BusinessCard.objects.filter(id=target_bacard_id).select_related('contact_detail')
Assuming id of BusinessCard is unique, you may want to use ...objects.get(id=target_bacard_id) inplace of ...objects.filter(id=target_bacard_id). Anyway select_related() will work on both ways.
select_related() is used for saving database query.
here is the documentation

How to set users.userid as a key in ndb

I'm trying to write appengine python code that uses the built-in authentication 'users' object and using userid as an ndb key
Here's my model:
class UserAccounts(ndb.Model):
UserID = ndb.KeyProperty(required=True)
In my handler:
I get the current user
user = users.get_current_user()
Instantiate an entry
account = Models.UserAccounts()
Set the userid to the ndb entry
account.UserID = userid
When I run it, I get this:
Expected Key, got '113804764227149124198'
Where am I going wrong? As much as possible, I'd like to use a KeyProperty instead of StringProperty for performance reasons.
by:
account.UserID = userid
I assume you meant:
account.UserID = user.user_id()
The user id is a string, not a key, so you can't use a KeyProperty here. In fact, AFAIK, User objects as returned from users.get_current_user() don't have a key (at least not one that is documented) since they aren't datastore entries. There is an ndb.UserProperty, but I don't think it's use is generally encouraged.
What performance reasons are you referring to?
I think what you want is something like this UserAccounts(id=user_id), this way the user_id is the key. With this approach you can remove the userid field from the model definition

Google Appengine Datastore I want to add primary_key

I have a ndb model and I use Python + google appengine. I want to add primary key to my first field "name". Forexample I added a name "Ada", after that if I want to add again "Ada", it mustnt add, it gives me an error. I can do it easily with django but I couldnt figure out with google appengine. Can you show me a solution way please. Here is my codes:
class User(ndb.Model):
username = ndb.StringProperty(indexed=False)
created_date = ndb.DateTimeProperty(auto_now_add=True)
updated_date = ndb.DateTimeProperty(auto_now_add=True)
You should use the get_or_insert() which will add a named key to your entity.
So if your username is name = 'Ada' you could do something like this:
user_db = User.get_or_insert(name.lower(), username=name)
The first parameter is the key_name and I used the lower() function just to make sure that they will be consistent and somebody with a name 'ADA' wouldn't be able to create a new entity, unless you want that.

Python Model with ReferenceProperty and join table

I believe this is trival but fairly new to Python.
I am trying to create a model using google app engine.
Basically from a E/R point of view
I have 2 objects with a join table (the join table captures the point in time of the join)
Something like this
Person | Idea | Person_Idea
-------------------------------
person.key idea.key person.key
idea.key
date_of_idea
my Python code would look like
class Person (db.Model):
#some properties here....
class Idea(db.Model):
#some properties here....
class IdeaCreated(db.Model):
person= db.ReferenceProperty(Person)
idea= db.ReferenceProperty(Idea)
created = db.DateTimeProperty(auto_now_add = True)
What I want to be able to do is have a convient way to get all ideas a person has (bypass idea created objects) -sometimes I will need the list of ideas directly.
The only way I can think to do this is to add the follow method on the User class
def allIdeas(self):
ideas = []
for ideacreated in self.ideacreated_set:
ideas.append(ideacreated.idea)
return ideas
Is this the only way to do this? I is there a nicer way that I am missing?
Also assuming I could have a GQL and bypass hydrating the ideaCreated instances (not sure the exact syntax) but putting a GQL query smells wrong to me.
you should use the person as an ancestor/parent for the idea.
idea = Idea(parent=some_person, other_field=field_value).put()
then you can query all ideas where some_person is the ancestor
persons_ideas = Idea.all().ancestor(some_person_key).fetch(1000)
the ancestor key will be included in the Idea entities key and you won't be able to change that the ancestor once the entity is created.
i highly suggest you to use ndb instead of db https://developers.google.com/appengine/docs/python/ndb/
with ndb you could even use StructuredProperty or LocalStructuredProperty
https://developers.google.com/appengine/docs/python/ndb/properties#structured
EDIT:
if you need a many to many relationship look in to ListProperties and store the Persons keys in that property. then you can query for all Ideas with that Key in that property.
class Idea(db.Model):
person = db.StringListProperty()
idea = Idea(person = [str(person.key())], ....).put()
add another person to the idea
idea.person.append(str(another_person.key())).put()
ideas = Idea.filter(person=str(person.key())).fetch(1000)
look into https://developers.google.com/appengine/docs/python/datastore/typesandpropertyclasses#ListProperty

Categories

Resources