1

设想

玩家参加活动。他们应该提供是否要参加活动的信息。

待解决的问题

如果他们计划参加特定活动,我想选择尚未提供信息的玩家。

你的目标

作为所用技术的初学者,我将感谢您的验证和建议,以改进我在下面建议的解决方案。

解决方案

技术: python、postgreSQL 和 Pony ORM

Pony ORM 中的实体模型:

class Event(db.Entity):
    _table_ = "event"
    start = Required(date)
    players = Set("Attendance")


class Player(db.Entity):
    _table_ = "player"
    first_name = Optional(str)
    last_name = Required(str)
    phone_number = Required(str)
    email = Required(str)
    events = Set("Attendance")


class Attendance(db.Entity):
    _table_ = "attendance"
    event = Required(Event)
    player = Required(Player)
    status = Required(bool)
    PrimaryKey(event, player)

主意:

  1. 获取参加活动时提供信息的玩家列表
  2. 获取不在 1 中创建的列表中的玩家列表。

该想法的当前实现:

players = select(p for p in Player if p not in select(p for p in Player
                 for a in Attendance if p == a.player and a.event == next_event))
4

1 回答 1

2

可以重构您的查询以使其更简单。首先,我们可以通过属性访问将内部查询PlayerAttendance内部查询的显式连接替换为隐式连接:

select(p for p in Player if p not in select(p for p in Player
       for attendance in p.events if attendance.event == next_event))

为了进一步简化查询,我们可以通过编写表达式来使用属性提升p.events.event

select(p for p in Player if p not in select(
       p for p in Player if next_event in p.events.event))

p.events表达式返回一组Attendance记录。在 Pony 中,当您有一个集合实例时,该集合具有其项目的所有属性,当您访问此类属性时,您将获得一组相应项目属性的所有值。表达式的值p.events.event将是Event与特定玩家链接的所有对象的集合。

简化查询的下一步是将生成器替换为 lambda。这样查询看起来有点短:

Player.select(lambda p: p not in Player.select(
    lambda p: next_event in p.events.event))

但是如果我们意识到内部查询是不必要的并且将查询重写为:

Player.select(lambda p: next_event not in p.events.event)

我认为这是使用 PonyORM 编写此查询的最简洁的方法

于 2016-09-01T12:36:51.620 回答