моделирование хранилища данных google / python


Привет я пытаюсь построить приложение, которое имеет модели, напоминающие что-то вроде следующих: - (в то время как было бы легко объединить две модели в одну и использовать их , но это не осуществимо в реальном приложении)

class User(db.Model):
     username=db.StringProperty()
     email=db.StringProperty()

class UserLikes(db.Model):
      username=db.StringProperty()
      food=db.StringProperty()

Цель-пользователь после входа в систему вводит еду, которая ему нравится, и приложение в свою очередь возвращает всех других пользователей, которым нравится эта еда. Теперь предположим, что пользователь Алиса вводит, что она любит "пиццу", это сохраняется в хранилище данных. Она выходит из системы и входит в систему again.At в этот момент мы запрашиваем хранилище данных для еды, которую она любит, а затем снова запрашиваем для всех пользователей, которым нравится эта еда. Это, как вы видите, два запроса к хранилищу данных, что не самый лучший способ. Я уверен, что был бы определенно лучший способ сделать это. Может кто-нибудь, пожалуйста, поможет.

[Update: - или можно сделать что-то подобное, что я изменю вторую модель таким образом, что имена пользователей станут многозначным свойством, в котором могут храниться все пользователи, которым нравится эта еда.. однако я немного неясно здесь]

[Edit: - Привет, Спасибо за ответ, но я нашел оба решения ниже немного излишним здесь. Я попытался сделать это, как показано ниже.Прошу вас взглянуть на это и дать добрый совет. Я сохранил те же две таблицы, однако изменил их, как показано ниже: -

class User(db.Model):
    username=db.StringProperty()
    email=db.StringProperty()

class UserLikes(db.Model):
     username=db.ListProperty(basestring)
     food=db.StringProperty()

Теперь, когда 2 пользователя обновляют одну и ту же еду, которую они любят, она хранится как

'пицца' - - - - > 'Алиса', ' Боб '

И мой запрос к БД для получения данных становится здесь довольно простым

query=db.Query(UserLikes).filter('username =','Alice').get()

Который я могу тогда Повторите как что-то вроде

    for elem in query.username:
          print elem

Теперь, если есть два продукта, как показано ниже: -

'pizza' ----> 'Alice','Bob'
'bacon'----->'Alice','Fred'

Я использую тот же запрос, что и выше, и перебираю запросы, а затем имена пользователей.

Я совершенно новичок в этом, чтобы понять, что это просто может быть неправильно. Пожалуйста, Предложите!
2 3

2 ответа:

Помимо модели отношений, которую вы имеете, вы можете справиться с этим двумя другими способами в зависимости от вашего конкретного случая использования. У вас есть хорошая идея в вашем обновлении, используйте свойство ListProperty. Проверьте taslk Бретта Слаткина на индексах отношений для некоторого фона.

Вы можете использовать дочернюю сущность (индекс отношений) для пользователя, содержащего список продуктов:

class UserLikes(db.Model):
    food = db.StringListProperty()

Затем, когда вы создаете экземпляр UserLikes, вы определяете пользователя, к которому он относится, как родитель:

likes = UserLikes(parent=user)

Это позволяет вам запрашивать других пользователей, которым нравится та или иная еда:

like_apples_keys = UserLikes.all(keys_only=True).filter(food='apples')
user_keys = [key.parent() for key in like_apples_keys]
users_who_like_apples = db.get(user_keys)

Однако, что может удовлетворить ваше приложение лучше, было бы сделать отношение ребенком еды:

class WhoLikes(db.Model):
    users = db.StringListProperty()

Задайте key_name для имени продукта при создании подобных:

food_i_like = WhoLikes(key_name='apples')

Теперь, чтобы получить всех пользователей, которые любят яблоки:

apple_lover_key_names = WhoLikes.get_by_key_name('apples')
apple_lovers = UserModel.get_by_key_names(apple_lover_key_names.users)

Чтобы получить всех пользователей, которым нравятся те же вещи, что и пользователю:

same_likes = WhoLikes.all().filter('users', current_user_key_name)
like_the_same_keys = set()
for keys in same_likes:
   like_the_same_keys.union(keys.users)
same_like_users = UserModel.get_by_key_names(like_the_same_keys)

Если у вас будет много лайков или много пользователей с тем же лайкам, вам нужно будет внести некоторые коррективы в процесс. Вы не сможете получить 1000 пользователей.

Пищевое и пользовательское отношение-это так называемоеМного-ко-многим отношение , типично обрабатываемое с помощью таблицы соединений; в этом случае БД .Модель , которая связывает пользователя и еду. Что-то вроде этого:

class User(db.Model):
  name = db.StringProperty()

  def get_food_I_like(self):
     return (entity.name for entity in self.foods)

class Food(db.Model):
  name = db.StringProperty()

  def get_users_who_like_me(self):
    return (entity.name for entity in self.users)

class UserFood(db.Model):
  user= db.ReferenceProperty(User, collection_name='foods')
  food = db.ReferenceProperty(Food, collection_name='users')

Для сущности данного пользователя вы можете получить предпочтительную пищу с помощью:

userXXX.get_food_I_like()

Для сущности данного продукта вы можете получить пользователей, которым нравится эта еда с помощью:

foodYYY.get_users_who_like_me()

Существует также другой подход к обработке отношений "многие ко многим", хранящий список ключей внутри db.ListProperty().

class Food(db.Model):
  name = db.StringProperty()

class User(db.Model):
  name = db.StringProperty()
  food = db.ListProperty(db.Key)

Помните, что ListProperty ограничен 5.000 ключами или, опять же, вы не можете добавить полезные свойства, которые идеально вписывались бы в таблицу join (например, количество звездочек, представляющих, насколько пользователь любит еду).