玩家参加活动。如果他们要去参加活动,他们应该提供信息。
如果他们计划参加特定活动,我想选择那些没有提供信息的玩家。
作为所使用技术的初学者,我将非常感谢您的验证和建议,以改进我在下面建议的解决方案。
技术: 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)
观
该想法的当前实施:
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))
答案 0 :(得分:2)
可以重构您的查询以使其更简单。首先,我们可以通过属性访问将内部查询中的Player
和Attendance
的显式连接替换为隐式连接:
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
编写此查询的最简洁方法