2015-06-02 11 views
5

I per la vita di me non riesco a capire il motivo per cui questa auto-referenziale molti-a-molti non sarà felice:autoreferenziale molti a molti pallone-sqlalchemy

minor_contains = db.Table(
    'minor_contains', 
    db.Column('parent_id', db.Integer, db.ForeignKey('minors.id'), 
      primary_key=True), 
    db.Column('contains_id', db.Integer, db.ForeignKey('minors.id'), 
      primary_key=True)) 

class Minor(db.Model): 
    __tablename__ = 'minors' 
    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String()) 
    ... 
    contains = db.relationship(
     "Minor", 
     secondary=minor_contains, 
     primaryjoin="id == minor_contains.c.parent_id", 
     secondaryjoin="id == minor_contains.c.contains_id", 
     backref="contained_by", 
     lazy='dynamic') 

Ho provato rielabora alcuni modi diversi basati su esempi che ho visto per SQLAlchemy e per Flask-SQLAlchemy, ma finisco costantemente dove o ottengo il seguente messaggio di errore o finisco in un loop infinito da qualche parte.

E ArgumentError: Impossibile trovare alcuna espressione di uguaglianza semplice che coinvolge le colonne di chiavi esterne mappate localmente per la condizione di join primario 'minor_contains.parent_id =: parent_id_1' sulla relazione Minor.contains. Assicurarsi che le colonne di riferimento siano associate a ForeignKey o ForeignKeyConstraint o siano annotate nella condizione di join con l'annotazione foreign(). Per consentire operatori di confronto diversi da '==', la relazione può essere contrassegnata come viewonly = True.

UPDATE

Sono davvero non riuscendo a capire il messaggio di errore perché dimostra la colonna dalla tabella join essere paragonato a se stesso, dove la condizione del join dovrebbe essere il PK della tabella minori rispetto all'FK nella tabella di join.

Aggiungerò anche una versione di questa che si blocca per sempre. Vedrai che ho rielaborato i nomi delle variabili e che ho appena riscritto più e più volte sperando che se mi prendo una nuova pugnalata, sarò in qualche modo più intelligente la seconda o la quinta volta.

minor_contains = db.Table(
    'minor_contains', 
    db.Column('parent_minor_id', db.Integer, db.ForeignKey('minors.id'), 
      primary_key=True), 
    db.Column('contains_minor_id', db.Integer, db.ForeignKey('minors.id'), 
      primary_key=True)) 

class Minor(db.Model): 
    __tablename__ = 'minors' 
    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String()) 
    ... 
    contains = db.relationship(
     "Minor", 
     secondary=minor_contains, 
     primaryjoin=id==minor_contains.c.parent_minor_id, 
     secondaryjoin=id==minor_contains.c.contains_minor_id, 
     backref=db.backref("minor_contains", lazy='dynamic')) 
+0

Hai mai risolto questo? Sto avendo lo stesso problema. – Ominus

risposta

0

Hai provato a farlo?

minor_contains = db.Table(
    'minor_contains', 
    db.Column('parent_id', db.Integer, db.ForeignKey('minors.id'), 
     primary_key=True), 
    db.Column('contains_id', db.Integer, db.ForeignKey('minors.id'), 
     primary_key=True)) 

class Minor(db.Model): 
    __tablename__ = 'minors' 
    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String()) 
    ... 
    contains = db.relationship(
     "Minor", 
     secondary=minor_contains, 
     primaryjoin="id == minor_contains.c.parent_id", 
     secondaryjoin="id == minor_contains.c.contains_id", 
     backref=db.backref('minor_contains', lazy='dynamic'), 
     lazy='dynamic') 
+0

Com'è diverso da ciò che l'op ha scritto? – davidism

+0

La penultima riga? –

+0

Sì, ma tutto ciò che hai fatto è stato rendere dinamico il backref, che non ha alcun rapporto con il problema. – davidism

1

Penso che sia necessario specificare il nome del modello nelle condizioni di join.

contains = db.relationship(
    "Minor", 
    secondary=minor_contains, 
    primaryjoin="Minor.id == minor_contains.c.parent_id", 
    secondaryjoin="Minor.id == minor_contains.c.contains_id", 
    backref=db.backref('minor_contains', lazy='dynamic'), 
    lazy='dynamic') 

Ho avuto lo stesso problema e ha risolto il problema. Ho trovato una risposta utile qui: link

+0

Il collegamento ipertestuale è stato di grande aiuto ... in particolare - "Quando ho definito una relazione autoreferenziale molti-a-molti, ho scoperto che la colonna chiave primaria deve essere definita nella tabella stessa. Non può essere definita nella base del modello o classe di mixin da cui deriva questa entità. " Questo da solo ha risolto il mio problema. – Krejko