如何使用现在的外键在SQLAlchemy中进行明显的连接?

时间:2018-01-24 12:50:06

标签: python sqlalchemy

我在SQLAlchemy中有两个模型:

class A(Base):
    __tablename__ = 'a'
    id = Column(Integer, primary_key=True)
    common = Column(Integer)
    text = Column(String)

class B(Base):
    __tablename__ = 'b'
    id = Column(Integer, primary_key=True)
    common = Column(Integer)
    url = Column(String)

这两个表之间没有外键,我需要使两个表的公共属性相同。我需要生成SQLALchemy查询,它选择表A中表B中没有相应公共值的所有文本,或者选择该行url == None。是否有任何简单的查询来使用SQLAlchemy会话来实现这一点?

2 个答案:

答案 0 :(得分:1)

q并不完全清楚,可能有一些变化:

from sqlalchemy import or_

class User(db.Model):
    id = Column(String, primary_key=True)
    common = Column(Integer)
    name = Column(db.String(128), index=True, unique=True)

class Dept(db.Model):
    id = Column(String, primary_key=True)
    common = Column(Integer)
    url = Column(String)


user1 = User(common=1)
user2 = User(common=2)
user3 = User(common=0)
dept1  = Dept( common = 0 )
dept2  = Dept( common = 1 )
dept3  = Dept( common = 3 )
dept3  = Dept( common = 4 )


common = db.session.query(User.common).distinct()
result = db.session.query(Dept).filter(Dept.common.notin_(common))
print([ r.common for r in result.all()] )
### filter dept.url:
result = db.session.query(Dept).filter(or_(Dept.common.notin_(common), Dept.url == 'xx'))

输出>> [3,4]

答案 1 :(得分:1)

如果我理解正确,你想要一个没有B的A,它有一个非NULL网址:

In [72]: session.query(A.text).\
    ...:     filter(~exists().where(and_(B.common == A.common,
    ...:                                 B.url != None)))
    ...:                                 
Out[72]: <sqlalchemy.orm.query.Query at 0x7f50131ce2b0>

In [73]: print(_)
SELECT a.text AS a_text 
FROM a 
WHERE NOT (EXISTS (SELECT * 
FROM b 
WHERE b.common = a.common AND b.url IS NOT NULL))

使用LEFT JOIN:

In [76]: session.query(A.text).\
    ...:     outerjoin(B, and_(B.common == A.common,
    ...:                       B.url != None)).\
    ...:     filter(B.id == None)
    ...:                       
Out[76]: <sqlalchemy.orm.query.Query at 0x7f5012f8d1d0>

In [77]: print(_)
SELECT a.text AS a_text 
FROM a LEFT OUTER JOIN b ON b.common = a.common AND b.url IS NOT NULL 
WHERE b.id IS NULL