bar*_*kin 83 python sql join sqlalchemy
我有以下SQLAlchemy映射类:
class User(Base):
__tablename__ = 'users'
email = Column(String, primary_key=True)
name = Column(String)
class Document(Base):
__tablename__ = "documents"
name = Column(String, primary_key=True)
author = Column(String, ForeignKey("users.email"))
class DocumentsPermissions(Base):
__tablename__ = "documents_permissions"
readAllowed = Column(Boolean)
writeAllowed = Column(Boolean)
document = Column(String, ForeignKey("documents.name"))
Run Code Online (Sandbox Code Playgroud)
我需要得到一个这样的表user.email = "user@email.com"
:
email | name | document_name | document_readAllowed | document_writeAllowed
Run Code Online (Sandbox Code Playgroud)
如何使用SQLAlchemy的一个查询请求?以下代码对我不起作用:
result = session.query(User, Document, DocumentPermission).filter_by(email = "user@email.com").all()
Run Code Online (Sandbox Code Playgroud)
谢谢,
Abd*_*der 78
试试这个
q = (Session.query(User,Document,DocumentPermissions)
.filter(User.email == Document.author)
.filter(Document.name == DocumentPermissions.document)
.filter(User.email == 'someemail')
.all())
Run Code Online (Sandbox Code Playgroud)
let*_*bee 43
一个好的风格是设置一些关系和一个主键用于权限(实际上,通常它是为所有设置整数主键的好方式,但无论如何):
class User(Base):
__tablename__ = 'users'
email = Column(String, primary_key=True)
name = Column(String)
class Document(Base):
__tablename__ = "documents"
name = Column(String, primary_key=True)
author_email = Column(String, ForeignKey("users.email"))
author = relation(User, backref='documents')
class DocumentsPermissions(Base):
__tablename__ = "documents_permissions"
id = Column(Integer, primary_key=True)
readAllowed = Column(Boolean)
writeAllowed = Column(Boolean)
document_name = Column(String, ForeignKey("documents.name"))
document = relation(Document, backref = 'permissions')
Run Code Online (Sandbox Code Playgroud)
然后用连接做一个简单的查询:
query = session.query(User, Document, DocumentsPermissions).join(Document).join(DocumentsPermissions)
Run Code Online (Sandbox Code Playgroud)
Ull*_*uri 24
正如@letitbee所说,最佳做法是将主键分配给表并正确定义关系以允许正确的ORM查询.话虽如此...
如果您有兴趣按以下方式编写查询:
SELECT
user.email,
user.name,
document.name,
documents_permissions.readAllowed,
documents_permissions.writeAllowed
FROM
user, document, documents_permissions
WHERE
user.email = "user@email.com";
Run Code Online (Sandbox Code Playgroud)
然后你应该去做类似的事情:
session.query(
User,
Document,
DocumentsPermissions
).filter(
User.email == Document.author
).filter(
Document.name == DocumentsPermissions.document
).filter(
User.email == "user@email.com"
).all()
Run Code Online (Sandbox Code Playgroud)
相反,如果你想做类似的事情:
SELECT 'all the columns'
FROM user
JOIN document ON document.author_id = user.id AND document.author == User.email
JOIN document_permissions ON document_permissions.document_id = document.id AND document_permissions.document = document.name
Run Code Online (Sandbox Code Playgroud)
然后你应该做的事情:
session.query(
User
).join(
Document
).join(
DocumentsPermissions
).filter(
User.email == "user@email.com"
).all()
Run Code Online (Sandbox Code Playgroud)
关于那个的一点说明......
query.join(Address, User.id==Address.user_id) # explicit condition
query.join(User.addresses) # specify relationship from left to right
query.join(Address, User.addresses) # same, with explicit target
query.join('addresses') # same, using a string
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请访问文档.
扩展Abdul的答案,您可以KeyedTuple
通过连接列来获取而不是离散的行集合:
q = Session.query(*User.__table__.columns + Document.__table__.columns).\
select_from(User).\
join(Document, User.email == Document.author).\
filter(User.email == 'someemail').all()
Run Code Online (Sandbox Code Playgroud)