2016-06-14 69 views

risposta

14

Invece di definire il livello "schema" i limiti ForeignKey creano un custom foreign condition; passa le colonne che desideri utilizzare come "chiavi esterne" e lo primaryjoin a relationship. È necessario definire manualmente il primaryjoin perché:

Per impostazione predefinita, tale valore viene calcolato sulla base delle relazioni di chiave esterna delle tabelle padre e figlio (o tabella di associazione).

In [2]: class A(Base): 
    ...:  a_id = Column(Integer, primary_key=True) 
    ...:  __tablename__ = 'a' 
    ...:  

In [3]: class C(Base): 
    ...:  c_id = Column(Integer, primary_key=True) 
    ...:  a_id = Column(Integer) 
    ...:  __tablename__ = 'c' 
    ...:  a = relationship('A', foreign_keys=[a_id], 
    ...:      primaryjoin='A.a_id == C.a_id') 
    ...:  

chiavi esterne possono anche essere annotati in linea nella primaryjoin utilizzando foreign():

a = relationship('A', primaryjoin='foreign(C.a_id) == A.a_id') 

È possibile verificare che non FOREIGN KEY vincoli vengono emessi per la tavola c:

In [4]: from sqlalchemy.schema import CreateTable 

In [5]: print(CreateTable(A.__table__)) 

CREATE TABLE a (
     a_id INTEGER NOT NULL, 
     PRIMARY KEY (a_id) 
) 



In [6]: print(CreateTable(C.__table__)) 

CREATE TABLE c (
     c_id INTEGER NOT NULL, 
     a_id INTEGER, 
     PRIMARY KEY (c_id) 
) 

Avviso:

Si noti che senza un vincolo FOREIGN KEY sul lato DB è possibile far saltare in pezzi l'integrità referenziale in qualsiasi modo desiderato. Esiste una relazione a livello di ORM/applicazione, ma non può essere applicata nel DB.