Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/361.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.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_Sql_Join_Sqlalchemy - Fatal编程技术网

Python sqlalchemy:如何通过一个查询连接多个表?

Python sqlalchemy:如何通过一个查询连接多个表?,python,sql,join,sqlalchemy,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 = Co

我有以下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"))
我需要为
user.email=”获得这样的表user@email.com“

如何使用SQLAlchemy的一个查询请求进行查询?以下代码不适用于我:

result = session.query(User, Document, DocumentPermission).filter_by(email = "user@email.com").all()
谢谢,

试试这个

q = Session.query(
         User, Document, DocumentPermissions,
    ).filter(
         User.email == Document.author,
    ).filter(
         Document.name == DocumentPermissions.document,
    ).filter(
        User.email == 'someemail',
    ).all()

一种好的方式是为权限设置一些关系和主键(实际上,通常是为所有内容设置整数主键的好方式,但无论如何):

然后使用联接执行简单查询:

query = session.query(User, Document, DocumentsPermissions).join(Document).join(DocumentsPermissions)

根据Abdul的答案展开,您可以通过连接列获得行集合,而不是离散的行集合:

q = Session.query(*User.__table__.columns + Document.__table__.columns).\
        select_from(User).\
        join(Document, User.email == Document.author).\
        filter(User.email == 'someemail').all()

此函数将生成所需的表作为元组列表

def get_documents_by_user_email(email):
    query = session.query(
       User.email, 
       User.name, 
       Document.name, 
       DocumentsPermissions.readAllowed, 
       DocumentsPermissions.writeAllowed,
    )
    join_query = query.join(Document).join(DocumentsPermissions)

    return join_query.filter(User.email == email).all()

user_docs = get_documents_by_user_email(email)

正如@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";
session.query(
    User
).join(
    Document
).join(
    DocumentsPermissions
).filter(
    User.email == "user@email.com"
).all()
那么你应该去做一些类似的事情:

session.query(
    User, 
    Document, 
    DocumentsPermissions
).filter(
    User.email == Document.author
).filter(
    Document.name == DocumentsPermissions.document
).filter(
    User.email == "user@email.com"
).all()
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

如果相反,您希望执行以下操作:

session.query(
    User, 
    Document, 
    DocumentsPermissions
).filter(
    User.email == Document.author
).filter(
    Document.name == DocumentsPermissions.document
).filter(
    User.email == "user@email.com"
).all()
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
然后你应该按照以下思路做一些事情:

SELECT
    user.email,
    user.name,
    document.name,
    documents_permissions.readAllowed,
    documents_permissions.writeAllowed
FROM
    user, document, documents_permissions
WHERE
    user.email = "user@email.com";
session.query(
    User
).join(
    Document
).join(
    DocumentsPermissions
).filter(
    User.email == "user@email.com"
).all()
关于这一点有一点值得注意

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

有关更多信息,请访问。

我发现以下方法可以联接两个表:
result=session.query(用户,文档)。从(联接(用户,文档)).filter(用户.电子邮件=='user@email.com“).all()
但我还没有设法使三个表的工作类似(包括DocumentPermissions)。你知道吗?当我执行类似的任务时,我会得到SyntaxError:keyword不能是一个表达式它能做什么样的
join
?内部、外部、交叉还是什么?这实际上根本不做连接,它返回元组中的行对象。在本例中,它将返回
[(,),…]
/“根本不进行连接”-这有点误导。它将具有类似sql的
从a、b、c中选择x
,这是一种交叉连接。然后过滤器将其设置为内部联接。您可以通过关闭
.all()
来打印查询。所以
print Session.query….
查看它到底在做什么。我对SQLAlchemy是新手。我注意到
.filter()
如果以逗号分隔,则可以接收多个条件。最好使用一个括号内带逗号分隔的
.filter()
,还是像上面的答案那样使用多个
.filter()
?最后一行中的
query
设置为什么?如何访问其中的连接记录?@pate我不确定“query设置为什么”是什么意思,但它将根据关系进行连接,并产生3个元组。query()调用的参数本质上是sqlalchemy中的选择列表。如何访问查询结果集中的
文档
(第二个元组值)?@PetrusTheron如我所说,查询将生成3个元组。您可以为元素编制索引,也可以在查询:print“Document:%s”%docWhoa,blast from the pass.中为(用户、文档、perm)解包:
“权限”是文档对象的一个属性,它为您提供一组DocumentPermission对象。因此,backref。这是有效的。但是,序列化对象时缺少列名。请执行此操作。请参阅-连接中没有指定很多内容。这是因为,如果tables/db模型已经在这些表之间设置了适当的外键,那么SQLAlchemy将为您连接适当的列。