Python flask sqlalchemy:查询一个表中的记录,而另一个表中没有相关记录(或具有特定值的记录)

Python flask sqlalchemy:查询一个表中的记录,而另一个表中没有相关记录(或具有特定值的记录),python,sqlalchemy,flask,flask-sqlalchemy,Python,Sqlalchemy,Flask,Flask Sqlalchemy,我正在编写一个简单的应用程序,帮助人们给选民打电话。我不想让我的志愿者多次骚扰任何选民。我怎样才能得到一份尚未被点名的选民名单?我在用烧瓶炼金术 投票人模型: class Voter(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(80)) phone = db.Column(db.String(20)) v

我正在编写一个简单的应用程序,帮助人们给选民打电话。我不想让我的志愿者多次骚扰任何选民。我怎样才能得到一份尚未被点名的选民名单?我在用烧瓶炼金术

投票人模型:

    class Voter(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(80))
        phone = db.Column(db.String(20))
        vanid = db.Column(db.String(20))
        address = db.Column(db.String(255))
        city = db.Column(db.String(255))
        zip_code = db.Column(db.String(20))
        lat  = db.Column(db.Float)
        lng = db.Column(db.Float)
        ...
调用模型:

    class Call(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        voter_id = db.Column(db.Integer, db.ForeignKey('voter.id'))
        voter = db.relationship('Voter', backref=db.backref('calls', lazy='dynamic'))
        user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
        user = db.relationship('User', backref=db.backref('calls', lazy='dynamic'))
        time = db.Column(db.DateTime)
        status_code = db.Column(db.String(20))
        ...
call.status_代码将包含诸如completed、busy、error_number等值

我想得到一份所有有资格被征召的选民名单,这样我就可以挑选一位为志愿者服务。(即call.status_code!=已完成等,或无相关通话记录)

如果要在原始SQL中执行此操作,我可能会:

Select [whatever]
FROM Voter v
LEFT JOIN Call c on c.voter_id = v.id
WHERE c.status_code IS NULL OR c.status_code = 'busy'

我无法在炼金术中找到答案。有什么见解吗?

您可能可以使用以下方法:

required_voters = db.session.query(Voter).outerjoin(Call).filter((Call.voter_id == None) | (Call.status_code != 'completed'))
编辑

提议的查询:

vwcc = db.session.query(distinct(Call.voter_id)).filter(Call.status_code == 'completed').subquery()
this will select all unique voters with completed calls
现在是主要部分

必需的投票者=db.session.query(Voter).outerjoin(Call.outerjoin(vwcc,vwcc.Voter\u id==Voter.id)).filter((vwcc.Voter\u id==None)和((Call.Voter\u id==None)|(Call.status\u code!='completed'))

我相信这将选出所有符合以下条件的选民: -没有已完成状态的呼叫 及 -没有呼叫或他们的呼叫没有完成状态
请记住,我是从脑海中写出来的,所以语法可能有点不正确

您特别回顾了SQLAlchemy对象关系教程了吗?这里是一个(基本的)你可能正在寻找的例子,尽管你必须考虑并发访问问题。code>session.query(Call).filter(Call.status\u code!=“completed”).order\u by(Call.time).first()(order\u by以最早的记录开始)更正:
session.query(Call.query).join(Voter).filter(Call.status\u code!=“completed”).order\u by(Call.time).first()
。谢谢Seberius-你能谈谈我下面评论中的问题在这种情况下是如何处理的吗?等等-在你进行上述查询之前,我不需要用某种分组方式过滤每个人的最新电话吗?假设一个投票者被标记为Call.status_code='busy',在以后的通话中被标记为'complete'。上述查询将在第三次通过时检查哪个呼叫?此查询将选择所有尚未接到呼叫或其呼叫未完成的投票者。这与您描述的场景不符(之前不清楚)。我的建议是使用Call.status_代码进行子查询,然后选择distinct Vorters(id),并使用该子查询进行筛选,而不是使用Call.status_代码!='“已完成”部分好的,我想我明白了,但可能需要你为我解释清楚。首先,我创建一个查询,查找任何已完成的调用。类似于
completes=db.session.query(Call.filter)(Call.status\u code==“complete”)
那么我需要以某种方式查询其id不包含在completes查询的投票者id列表中的投票者?我该怎么写呢?正如@Pawel所说,你想做的事情有点复杂。你必须首先考虑如何优先考虑选民,因为这会影响你想查询的方式。它还遇到了并发问题,请考虑:志愿者1请求一个新的投票者。几秒钟后,志愿者2请求一个投票者并获得相同的投票者,因为V1尚未完成呼叫并更新投票者的状态代码。V1完成呼叫,V2收到忙信号。V1表示呼叫已完成,但V2速度较慢,并用busy覆盖状态代码。使用建议的查询编辑了我的答案