How do I get StructuredProperty's in Google App Engine to update? - python

I have a Player model that is assigned to a Team. When I assign them to a Team I see the correct team name show up when I access player.team.name. If I go to the Team and rename it, the player.team.name still returns the old team name.
A player is assigned to "New Orleans Hornets". The player.team.name is "New Orleans Hornets".
Rename "New Orleans Hornets" team to "New Orleans Pelicans". The player.team.name is still "New Orleans Hornets".
Code:
class Team(ndb.Model):
name = ndb.StringProperty()
class Player(ndb.Model):
name = ndb.StringProperty()
team = ndb.StructuredProperty(Team)
I have a feeling I need to use a KeyProperty here but can't figure out how that would work. Any help is appreciated.

The StructuredProperty stores the Team entity within the Player entity (ie.It has a copy of the team). So you would need to find each Player who is a member of the team and updated the Player.team entry with the new name.
Using a KeyProperty will store a reference to the Team entity. When retrieving a Player, you will need to do a separate get call to retrieve the associated Team.
The model will look something like:
class Team(ndb.Model):
name = ndb.StringProperty()
class Player(ndb.Model):
name = ndb.StringProperty()
team = ndb.KeyProperty(kind=Team)
To store a Player with a team:
team = #look up an existing team entity
player = Player()
player.name = "Joe"
player.team = team.key()
player.put()
To retrieve a Player with their team name you would:
player = ....
players_team = Team.get_by_id(player.team)
players_team.name # to access the name

Related

Type Object '... ' has no attribute name '... '

I keep on getting the no attribute error in python. I want to make a class for cities to put into a program I am writing (Im trying to learn python on the side while working). I basically want to be able to put data into a class for cities and use that in another place. I guess, I would need to know how to access attributes from a class. Im probably doing a bunch wrong so any feedback would be helpful
class City:
def __init__(self, name, country, re_growth10):
self.name = name #name of the city
self.country = country #country the city is in
self.re_growth10 = re_growth10 #City Real estate price growth over the last 10 years
def city_Info(self):
return '{}, {}, {}'.format(self.name, self.country, self.re_growth10)
Toronto = City("Toronto", "Canada", 0.03) #Instance of CITY
Montreal = City("Montreal", "Canada", 0.015) #Instance of CITY
user_CityName = str(input("What City do you want to buy a house in?")) #user input for city
def city_Compare(user_CityName): #Compare user input to instances of the class
cities = [Toronto, Montreal]
for City in cities:
if City.name == user_CityName:
print(City.name)
else:
print("We Don't have information for this city")
return ""
print(City.name)
You are getting confused because you have a variable that has the same name as your class, City. To avoid this, use lower-case names for variables. Once you change this, you get a different error:
NameError: name 'city' is not defined
The reason is that you are trying to print the name of a variable which is defined inside a function, but the print statement is outside the function. To fix this, put your last print statement inside the function city_Compare, and call that function (which you never do).
Or change the function to return an object instead of printing it:
def find_city(name):
cities = [Toronto, Montreal]
for city in cities:
if city.name == name:
return city
return None
city_name = input("What City do you want to buy a house in?")
city = find_city(city_name)
if city is not None:
print(city.name)
else:
print("We Don't have information for this city")

NDB StructuredProperty query unexpected result

I have this model:
class State(ndb.Model):
code = ndb.StringProperty(required=True)
name = ndb.StringProperty(required=True)
city_list = ndb.StructuredProperty(City, repeated=True)
country = ndb.KeyProperty(required=True)
class City(ndb.Model):
code = ndb.StringProperty(required=True)
name = ndb.StringProperty(required=True)
I implemented this query:
stateData = State.query( State.city_list.name == 'xyz', State.name=='Punjab' ).fetch()
I want to implement query on State where name is Punjab. But Punjab has many cities, so I filtered by city name xyz.
I'm expecting only the xyz city but I'm getting all the cities in the result.
How can I get just the xyz city in the result?
You're querying for State kinds, so results will be State entities, with their complete city_list property - you can't get just a subset of the city_list. So what you're getting is expected.
You could maybe do a projection query, in which case you'd get a list of State entities, each with just a single city in city_list, see Projections and multiple-valued properties. Watch out for the limitations.
Or you could redesign your models, maybe with separate City entities you can query for directly (instead of structured properties inside the State entity).
you should filter before you fetch. the below syntax is based on an older version of ndb where you use Key property
class State(ndb.Model):
code = ndb.StringProperty(required=True)
name = ndb.StringProperty(required=True)
city_list = ndb.KeyProperty(kind=City, repeated=True)
country = ndb.KeyProperty(required=True)
stateq = State.query( State.name=='Punjab' )
city=stateq.filter(State.City==citykey)
result=city.fetch()
I did not try but it will probably work for structured property as well.

Django ORM : Categorizing a list query on multiple foreign keys

My title may seem vague, but I'm sorry to save I have no other idea on how to phrase this. Assuming my model structure looks like this:
class Restaurant(models.Model):
name = models.CharField(...necessary stuff...)
class Cuisine(models.Model):
name = models.CharField(...necessary stuff...)
# thai chinese indian etc.
class Food(models.Model):
restaurant = models.ForeignKey(Restaurant, related_name='restaurant')
cuisine = models.ForeignKey(Cuisine, related_name='cuisine')
name = models.CharField(...)
What I want is a list of objects of Food of a specific restaurant. But the Food objects need to be under their respective Cuisine, so that I can easily access the Food through the context. Is it possible to achieve this in any way?
My current query:
q = Cuisine.objects.prefetch_related('cuisine')
q = q.filter(cuisine__restaurant_id=restaurant.id) # say restaurant.id=1
# here restaurant is the object which I have retrieved
Well, what it does is it filters the cuisines available to the restaurant, but lists all food within those cuisine. I want only the food available in the restaurant. I think I am missing something in the way I built my models, but I'm not certain. It would be really helpful if someone could point me to the right direction. Thanks.
Food.objects.filter(restuarant_id=1, cuisine_id__in=selected_cuisine_ids)
Here, selected_cuisine_ids is the list of IDs of whichever cuisines needed
In my opinion, you should use ManyToManyField with through argument. So your models should be like:
class Restaurant(models.Model):
name = models.CharField(...necessary stuff...)
cuisines = models.ManyToManyField(Restaurant, through='Food', related_name='restaurants')
class Cuisine(models.Model):
name = models.CharField(...necessary stuff...)
# thai chinese indian etc.
class Food(models.Model):
restaurant = models.ForeignKey(Restaurant, related_name='restaurant')
cuisine = models.ForeignKey(Cuisine, related_name='cuisine')
name = models.CharField(...)
In this way, your query would be like this:
Cuisine.objects.filter(restaurants__id=1)

How to created inherited objects using Python?

I have the following nested dict:
world = {'europe' :
{'france' : ['paris', 'lion'],
'uk' : ['london', 'manchester']}},
{'asia' :
{'china' : ['beijing'],
{'japan' : ['tokyo']}}
I'm trying the following objects out of it:
class world:
continents = {} # dict of continents
class continent(world):
name = '' # name of the continent
countries = {} # dict of countries
class country(continent):
name = '' # name of the country
cities = [] # list of cities
class city(country):
name = '' # name of the city
The goal is to get all countries from the continent object and alternatively to get the country and the continent names from a city object.
What is the best way to do so in Python?
Inheriting from "higher" classes is incorrect here. If you inherit a class, that inheriting class is the parent class plus more. You're saying here that country is a continent and also is a world. That is clearly not true and unnecessary.
There is no necessary hierarchical relationship between those four classes. Worlds are worlds, continents are continents, countries are countries and cities are cities. It's enough for continents to contain a list of the countries they hold, or conversely for a country to hold a reference to the continent it's in. The classes themselves do not need a hierarchical relationship.
Consider also whether such a strict 1:1 relationship is useful. There are countries which exist on more than one continent, depending on how exactly you want to define these terms (colonies are fun). How to design this data structure really depends on the concrete goal you have for it.
Syntactically, the classes should be defined as
class World(object):
def __init__(self, continents):
self.continents = continents
class Continent(World):
def __init__(self, name):
self.name = '' # name of the continent
...
class Country(Continent):
def __init__(self, name):
self.name = '' # name of the country
...
class City(Country):
def __init__(self, name):
self.name = '' # name of the city
...
However, in this case it does not make any sense.
Subclassing means something else:
Class Animal(object):
pass
Class Dog(Animal):
pass
Class Snake(Animal):
pass
A dog is a specific type of animal. A dog is an animal. A snake is also an animal.
In your case, a Continent is not a type of World, a Country is not a type of Continent and so on.
Instead you want to relate those classes, which can live as separate classes or they can go one inside the other.
For example
class City(object):
def __init__(self, name):
self.name = '' # name of the city
class Country(object, cities):
def __init__(self, name, cities):
self.name = name # name of the country
self.cities = cities # it's a list of Cities instances
class Continent(object):
def __init__(self, name, countries):
self.name = name # name of the continent
self.countries = countries # it's a list of Countries instances
class World(object):
def __init__(self, continents):
self.continents = continents # it's a list of Continent instances
france = Country('France', [City('Paris'), City('Annecy'), City('St. Tropez')])
italy = Country('Italy', [City('Rome'), City('Milan')])
uk = Country('UK', [City('London'), City('Bath')])
europe = Continent('europe', [france, italy, uk])
...
Note: the above is just an example. It may not be the best way to do it in python for a number of reasons, depending on how you intend to manipulate the objects.
It's a wide and long subject.
I suggest to look online for a good tutorial about Object Orientation (also called OOP for Object Oriented Programming or OOD for Object Oriented Design).
Here is one tutorial, but there are thousands available online.
After that, you will be able to design the interfaces your objects should expose in order to offer a certain functionality at the local/application level.
Tip: using a RDBM (Relational Data Base Management System), would help you relating and managing the models. Learn about ERD's (Entity-Relationship Diagrams) to help you design your data model.
:)

Query between three tables, many to many relationship

I have three databases in GAE. Hobby, Attendee and Event.
class Hobby(db.Model):
name = db.StringProperty()
htest = Hobby.get_or_insert('tennis')
htest.name = 'tennis'
htest.put()
htest = Hobby.get_or_insert('basketball')
htest.name = 'basketball'
htest.put()
htest = Hobby.get_or_insert('food')
class Event(db.Model):
title = db.StringProperty(required=True)
description = db.TextProperty()
time = db.DateTimeProperty()
location = db.TextProperty()
creator = db.UserProperty()
edit_link = db.TextProperty()
gcal_event_link = db.TextProperty()
gcal_event_xml = db.TextProperty()
hobby = db.ReferenceProperty(Hobby)
class Attendee(db.Model):
email = db.StringProperty()
hobbies = db.ListProperty(db.Key)
event = db.ReferenceProperty(Event)
Each Attendee can pick however many hobby as they desire. When a event is created, user chooses a hobby to associate the event with and invitation will be send to every attendee who has chosen that hobby. Hobby DB is preloaded database.
I want to make a query that does that.
after reading Nick's blog
http://blog.notdot.net/2010/10/Modeling-relationships-in-App-Engine
which was very helpful I feel like I'm supposed to use the method that was mentioned in there
attendees = Attendee.all()filter('hobbies =', basketball).fetch(100)
however, i'm stuck there... any help would be really appreciated.
I think you should record the invitations send in a table, say "invitationsSend" with two fields : event and attendee, which two fields are making a unique primary key.
To build this, you will have to select the data between both your tables event and attendees :
insert into invitationsSend(select E.Event, A.Attendee from Event as E, Attendee as A where E.Hobby = A.Hobby)
But I'm not familiar with your "db.listProperty" used for "hobbies" and I do not know how to look into that list. I should do this as a separate table with data "Attendee, Hobby", both as primary key.
Regards,

Categories

Resources