J'ai les classes mappées SQLAlchemy suivantes:
class User(Base):
__table= 'users'
email = Column(String, primary_key=True)
name = Column(String)
class Document(Base):
__table= "documents"
name = Column(String, primary_key=True)
author = Column(String, ForeignKey("users.email"))
class DocumentsPermissions(Base):
__table= "documents_permissions"
readAllowed = Column(Boolean)
writeAllowed = Column(Boolean)
document = Column(String, ForeignKey("documents.name"))
J'ai besoin d'une table comme celle-ci pour user.email = "[email protected]"
:
email | name | document_name | document_readAllowed | document_writeAllowed
Comment cela peut-il être fait en utilisant une requête de requête pour SQLAlchemy? Le code ci-dessous ne fonctionne pas pour moi:
result = session.query(User, Document, DocumentPermission).filter_by(email = "[email protected]").all()
Merci,
Essaye ça
q = (Session.query(User,Document,DocumentPermissions)
.filter(User.email == Document.author)
.filter(Document.name == DocumentPermissions.document)
.filter(User.email == 'someemail')
.all())
Un bon style serait d’établir des relations et une clé primaire pour les permissions (en fait, c’est un bon style pour installer entier clés primaires pour tout, mais peu importe):
class User(Base):
__table= 'users'
email = Column(String, primary_key=True)
name = Column(String)
class Document(Base):
__table= "documents"
name = Column(String, primary_key=True)
author_email = Column(String, ForeignKey("users.email"))
author = relation(User, backref='documents')
class DocumentsPermissions(Base):
__table= "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')
Ensuite, faites une requête simple avec des jointures:
query = session.query(User, Document, DocumentsPermissions).join(Document).join(DocumentsPermissions)
Comme @letitbee l'a dit, il est préférable d'affecter des clés primaires aux tables et de définir correctement les relations pour permettre une interrogation ORM correcte. Cela étant dit...
Si vous souhaitez rédiger une requête dans le sens suivant:
SELECT
user.email,
user.name,
document.name,
documents_permissions.readAllowed,
documents_permissions.writeAllowed
FROM
user, document, documents_permissions
WHERE
user.email = "[email protected]";
Ensuite, vous devriez aller pour quelque chose comme:
session.query(
User,
Document,
DocumentsPermissions
).filter(
User.email == Document.author
).filter(
Document.name == DocumentsPermissions.document
).filter(
User.email == "[email protected]"
).all()
Si au lieu de cela, vous voulez faire quelque chose comme:
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
Ensuite, vous devriez faire quelque chose comme:
session.query(
User
).join(
Document
).join(
DocumentsPermissions
).filter(
User.email == "[email protected]"
).all()
Une note à ce sujet ...
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
Pour plus d'informations, visitez le site docs .
En développant la réponse d'Abdul, vous pouvez obtenir un KeyedTuple
au lieu d'une collection discrète de lignes en joignant les colonnes:
q = Session.query(*User.__table__.columns + Document.__table__.columns).\
select_from(User).\
join(Document, User.email == Document.author).\
filter(User.email == 'someemail').all()
Cette fonction produira la table requise sous forme de liste de n-uplets.
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)