Python SQLAlchemy M2M关系查询
我有以下模型,我正在尝试列出所有最新的DocumentVersions,它们在用户组中有一个组Python SQLAlchemy M2M关系查询,python,sqlalchemy,Python,Sqlalchemy,我有以下模型,我正在尝试列出所有最新的DocumentVersions,它们在用户组中有一个组 class User(Base, BaseModel): __tablename__ = 'users' id = Column(Integer, primary_key=True) email = Column(Unicode(EMAIL_LENGTH), unique=True, nullable=False) full_name = Column(Unicode(
class User(Base, BaseModel):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
email = Column(Unicode(EMAIL_LENGTH), unique=True, nullable=False)
full_name = Column(Unicode(FULL_NAME_LENGTH), nullable=False)
deleted = Column(Boolean, nullable=False, default=False)
document_versions = relationship(
'DocumentVersion',
backref="author")
class Group(Base, BaseModel):
__tablename__ = 'groups'
__table_args__ = (UniqueConstraint('name','company_id'),)
id = Column(Integer, primary_key=True)
name = Column(Unicode(60), nullable=False)
deleted = Column(Boolean, nullable=False, default=False)
# Companies have many groups
company_id = Column(
Integer,
ForeignKey('companies.id'),
nullable=False)
roles = relationship("Role",
primaryjoin="Group.id==Role.group_id",
backref="group")
users = relationship("User",
secondary=group_user,
backref="groups")
document_version_group = Table(
"document_version_groups",
Base.metadata,
Column('group_id', Integer, ForeignKey('groups.id')),
Column('document_version_id', Integer, ForeignKey('document_versions.id')))
class DocumentVersion(Base, BaseModel):
__tablename__ = 'document_versions'
id = Column(Integer, primary_key=True)
document_id = Column(
Integer,
ForeignKey('documents.id'),
nullable=False)
author_id = Column(
Integer,
ForeignKey('users.id'),
nullable=False)
groups = relationship(
"Group",
secondary=document_version_group,
lazy='dynamic', # This is newly added just now
backref="document_versions")
status = Column(
Enum(
"draft",
"review",
"approval",
"declined",
"approved",
name="status"),
default="draft",
nullable=False)
我尝试了以下方法,但没有成功(请注意,返回的文档\u版本没有组)
>>docs=session.query(DocumentVersion).filter(Document.company==user.company).filter(Group.id.in_uuz([g.id代表g in user.groups])).all()
2012-08-31 15:14:19651信息[sqlalchemy.engine.base.engine][main thread]选择document_versions.id作为document_versions_id,document_versions.document_id作为document_versions_document_id,document_versions.document_current_草稿_id作为document_versions_current_草稿_id,文档\u版本。文档\u当前\u活动\u id作为文档\u版本\u当前\u活动\u id,文档\u版本。作者\u id作为文档\u版本\u作者\u id,文档\u版本。状态作为文档\u版本\u状态,文档\u版本。主要版本作为文档\u版本\u主要版本,文档\u版本。次要版本作为文档\u版本\u次要版本
来自文档\u版本、文档、组
其中%(参数1)s=documents.company_id和groups.id IN(%(id_1)s)
2012-08-31 15:14:19651信息[sqlalchemy.engine.base.engine][MainThread]{'id_1':1,'param_1':1}
>>>[d.groups.all()表示文档中的d]
2012-08-31 15:15:29996信息[sqlalchemy.engine.base.engine][main]选择groups.id作为groups\u id,groups.name作为groups\u name,groups.deleted作为groups\u deleted,groups.company\u id作为groups\u company\u id
从组、文档\u版本\u组
其中%(参数1)s=文档版本组。文档版本组id和组。id=文档版本组。组id
2012-08-31 15:15:29996信息[sqlalchemy.engine.base.engine][MainThread]{'param_1':1}
2012-08-31 15:15:29998信息[sqlalchemy.engine.base.engine][MainThread]选择groups.id作为groups\u id,groups.name作为groups\u name,groups.deleted作为groups\u deleted,groups.company\u id作为groups\u company\u id
从组、文档\u版本\u组
其中%(参数1)s=文档版本组。文档版本组id和组。id=文档版本组。组id
2012-08-31 15:15:29998信息[sqlalchemy.engine.base.engine][MainThread]{'param_1':2}
[[], []]
假设此SQL给出正确的结果:
SELECT *
FROM document_versions
WHERE
EXISTS (
SELECT 1
FROM documents
WHERE
document_versions.document_id = documents.id
AND documents.company_id = :company_id
)
AND EXISTS (
SELECT 1
FROM document_version_groups
WHERE
document_versions.id = document_version_groups.document_version_id
AND document_version_groups.group_id IN :group_ids
)
那么以下SQLAlchemy表达式应该可以工作:
session.query(DocumentVersion).filter(and_(
DocumentVersion.document.has(compay=user.company),
DocumentVersion.groups.any(
Group.id.in_([g.id for g in user.groups])
),
)).all()
请注意关系属性DocumentVersion.document
和DocumentVersion.groups
的明确使用。如果没有它们,查询将只由一堆不相关的表组成,从而得到假阳性结果
session.query(DocumentVersion).filter(and_(
DocumentVersion.document.has(compay=user.company),
DocumentVersion.groups.any(
Group.id.in_([g.id for g in user.groups])
),
)).all()