2012-05-21 2 views
0

J'essaie de charger une propriété auto-relation avec l'option contains_eager afin d'éviter deux jointures lors de la commande ou de la recherche en utilisant l'une des colonnes relationnelles. Mes objets modèle semble que:Impossible de remplir une relation auto-chargée

class Usuario(DeclarativeBase): 
    __tablename__ = 'usuarios' 
    __table_args__ = {'mysql_engine':'InnoDB'} 

    id=Column(Integer, primary_key=True) 
    usuario=Column(Text) 
    ... 
    resellers_id=Column(Integer, ForeignKey('usuarios.id')) 
    .... 
    reseller = relation('Usuario', remote_side = [id]) 

J'utilise pour obtenir les données:

u= DBSession.query(Usuario).options(contains_eager('reseller'))\ 
      .outerjoin(self.usuarios_padre, Usuario.resellers_id == self.usuarios_padre.id)\ 
      .filter(Usuario.id=1)\ 
      .order_by(self.usuarios_padre.usuario).one() 

self.usuarios_padre est un alias de Usuario

Si j'accéder u.reseller .usuario Je reçois le même que u.usuario à la place obtenir usuario du parent

Une idée où le problème est? J'ai essayé de définir la relation en utilisant paresseux = "joint" sans résultat.

Cordialement

Répondre

1

Le problème est que vous chargez deux ensembles de Usuario objets dans une requête, et afin de résoudre le problème, vous devez utiliser le aliased puis explicitement spécifiez le crénelage parent dans le join et le contains_eager:

qry = session.query(Usuario).filter(Usuario.id==1) 

# join using the aliased. Use *outerjoin* in order to still get the result for those without a parent 
res = aliased(Usuario) 
qry = qry.outerjoin((res, Usuario.reseller)) 

# specify which table/alias represents the *contained* relationship 
qry = qry.options(contains_eager(Usuario.reseller, alias=res)) 
Questions connexes