Eu tenho as seguintes classes mapeadas 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"))
Preciso conseguir uma mesa como esta para user.email = "[email protected]"
:
email | name | document_name | document_readAllowed | document_writeAllowed
Como isso pode ser feito usando uma solicitação de consulta para SQLAlchemy? O código abaixo não funciona para mim:
result = session.query(User, Document, DocumentPermission).filter_by(email = "[email protected]").all()
Obrigado,
python
sql
join
sqlalchemy
Barankin
fonte
fonte
result = session.query(User, Document).select_from(join(User, Document)).filter(User.email=='[email protected]').all()
Mas ainda não consegui fazer funcionar de forma semelhante para três tabelas (para incluir DocumentPermissions). Qualquer ideia?Respostas:
Tente isto
fonte
join
isso faz? interno, externo, cruzado ou o quê?[(<user>, <document>, <documentpermissions>),...]
/select x from a, b ,c
que é uma junção cruzada. Os filtros então a tornam uma junção interna..all()
. Então,print Session.query....
para ver exatamente o que ele está fazendo..filter()
pode receber vários critérios se separados por vírgulas. É preferível usar um.filter()
com separações por vírgula entre parênteses ou usar vários.filter()
como a resposta acima?Um bom estilo seria configurar algumas relações e uma chave primária para permissões (na verdade, geralmente é um bom estilo configurar chaves primárias inteiras para tudo, mas tanto faz):
Em seguida, faça uma consulta simples com junções:
fonte
query
definido na última linha e como você acessa os registros combinados nela?Document
(valor da 2ª tupla) no conjunto de resultados da consulta?for (user, doc, perm) in query: print "Document: %s" % doc
Como @letitbee disse, sua melhor prática é atribuir chaves primárias às tabelas e definir adequadamente os relacionamentos para permitir a consulta ORM adequada. Dito isto ...
Se você estiver interessado em escrever uma consulta ao longo das linhas de:
Então você deve ir para algo como:
Em vez disso, você deseja fazer algo como:
Então você deve fazer algo como:
Uma nota sobre isso ...
Para obter mais informações, visite os documentos .
fonte
Expandindo a resposta de Abdul, você pode obter um em
KeyedTuple
vez de uma coleção discreta de linhas unindo as colunas:fonte
Esta função produzirá a tabela necessária como uma lista de tuplas.
fonte