Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用“不包含”一对多筛选SQLAlchemy_Python_Sqlalchemy - Fatal编程技术网

Python 使用“不包含”一对多筛选SQLAlchemy

Python 使用“不包含”一对多筛选SQLAlchemy,python,sqlalchemy,Python,Sqlalchemy,我试图查询和过滤一对多的关系,但似乎不知道如何做到这一点 以下是为简洁起见修剪的映射: class Bug(Base): __tablename__ = 'bug' id = Column('bug_id', Integer, primary_key=True) tags = relationship('Tag', backref='bug') class Tag(Base): id = Column('tag_id', Integer, primary_key

我试图查询和过滤一对多的关系,但似乎不知道如何做到这一点

以下是为简洁起见修剪的映射:

class Bug(Base):
    __tablename__ = 'bug'
    id = Column('bug_id', Integer, primary_key=True)
    tags = relationship('Tag', backref='bug')

class Tag(Base):
    id = Column('tag_id', Integer, primary_key=True)
    name = Column('tag_name', String)
    bug_id = Column('bug_id', ForeignKey('bug.bug_id'))

我希望能够找到所有没有名为foo的标记的Bug。

我不确定标记表应该为您表示什么,但奇怪的是,您的模式将每个标记与一个Bug关联起来。如果您想用相同名称的标记标记多个bug,您将在标记类中创建多个同名行。这似乎违反了法律

在数据库中描述标记云的标准方法是使用多对多关系和二级关联表,二级关联表关联bug、标记对。SQLAlchemy文档有一个

如果您坚持按原样使用模式,有几种方法可以做到这一点

客户端过滤 这显然效率低下,但很容易理解。一个接一个地检查bug,一个接一个地检查它们的标记,并消除tag.name==foo:

两个问题 找到所有标记为foo的不同bug,然后找到该集合的补充

此版本正好使用数据库的两个查询:

foo_bugs = [t.bug_id for t in session.query(Tag).filter_by(name="foo").distinct()]
session.query(Bug).filter(~Bug.id.in_(foo_bugs))
带子查询的一个查询 与上面相同,但将foo_bug设为子查询,因为没有理由在客户端获取其内容:

foo_bugs = session.query(Tag.bug_id).filter_by(name="foo").distinct().subquery()
session.query(Bug).filter(~Bug.id.in_(foo_bugs))

这将是一个不相关的子查询,因此从服务器的角度来看,它应该像两个单独的查询一样进行优化。

我不确定标记表应该为您表示什么,但奇怪的是,您的模式将每个标记与一个Bug相关联。如果您想用相同名称的标记标记多个bug,您将在标记类中创建多个同名行。这似乎违反了法律

在数据库中描述标记云的标准方法是使用多对多关系和二级关联表,二级关联表关联bug、标记对。SQLAlchemy文档有一个

如果您坚持按原样使用模式,有几种方法可以做到这一点

客户端过滤 这显然效率低下,但很容易理解。一个接一个地检查bug,一个接一个地检查它们的标记,并消除tag.name==foo:

两个问题 找到所有标记为foo的不同bug,然后找到该集合的补充

此版本正好使用数据库的两个查询:

foo_bugs = [t.bug_id for t in session.query(Tag).filter_by(name="foo").distinct()]
session.query(Bug).filter(~Bug.id.in_(foo_bugs))
带子查询的一个查询 与上面相同,但将foo_bug设为子查询,因为没有理由在客户端获取其内容:

foo_bugs = session.query(Tag.bug_id).filter_by(name="foo").distinct().subquery()
session.query(Bug).filter(~Bug.id.in_(foo_bugs))
这将是一个不相关的子查询,因此从服务器的角度来看,它应该像两个单独的查询一样进行优化。

您可以在关系上使用any操作符

bugs_without_foo = session.query(Bug).filter(
    db.not_(Bug.tags.any(Tag.name == 'foo'))
).all()
它看起来更好,但它比Dan Lenski答案中的子查询要好。

您可以在关系上使用any操作符

bugs_without_foo = session.query(Bug).filter(
    db.not_(Bug.tags.any(Tag.name == 'foo'))
).all()

它看起来更好,但它比Dan Lenski答案中的子查询要好。

您对数据映射错误的评估是正确的。实际上,我正在映射一个我拥有只读访问权限的现有数据库结构,所以我正在处理我所拥有的。感谢您提供完整的答案和多个选项!您对错误数据映射方式的评估是正确的。实际上,我正在映射一个我拥有只读访问权限的现有数据库结构,所以我正在处理我所拥有的。感谢您提供完整的答案和多个选项!