2014-09-21 17 views
7

Sono nuovo in sqlalchemy. Ho seguito il tutorial per creare l'Automap di un db esistente con rapporto da un DB MySQLÈ possibile dichiarare una relazione dopo che la classe è stata creata da automap in SqlAlchemy

from sqlalchemy import create_engine, MetaData, Column, Table, ForeignKey 
from sqlalchemy.ext.automap import automap_base, generate_relationship 
from sqlalchemy.orm import relationship, backref 
from config import constr, mytables 

def _gen_relationship(base, direction, return_fn, 
        attrname, local_cls, refferred_cls, **kw): 
    return generate_relationship(base, direction, return_fn, attrname, local_cls, refferred_cls, **kw) 

engine = create_engine(constr) 
metadata = MetaData() 
metadata.reflect(engine, only=mytables) 
Base = automap_base(metadata=metadata) 
Base.prepare(engine, reflect=True, generate_relationship=_gen_relationship) 
Tableclass1 = Base.classes.table1 
Tableclass2 = Base.classes.table2 

Table2.ID mappe ad una delle colonne table1 s'. Ma quando stavo cercando di utilizzare query e join table1 e table2, riporta un errore che dice "Impossibile trovare relazioni con le chiavi esterne". Dal momento che conosco la relazione di queste 2 tabelle, c'è modo per me di dichiarare questa relazione dopo che l'istanza della classe è stata creata? O c'è modo di dire esplicitamente questa relazione nella funzione di ricerca? Grazie!

risposta

0

È possibile farlo in modo esplicito utilizzando onclause paremeter del metodo join di SQLAlchemy. Il misuratore onclause viene utilizzato in modo simile a JOIN di SQL, ad es.

sqlalchemy.orm.join(table1, table2, onclause=table2.ID == table1.your_attribute) 

Potete anche stato bypassare l'esistenza di chiave esterna nel database, semplicemente indicando la chiave esterna nella classe:

Column('ID', Integer, ForeighKey('table1.your_attribute')) 
3

Mentre è possibile farlo nella query come accennato @mpolednik , se leggo correttamente la tua domanda, la soluzione ideale sarebbe quella di dichiarare la relazione nelle tue classi per uso ripetuto.

Esso può essere ottenuto semplicemente pre-dichiarando la classe che si desidera utilizzare, in questo modo:

from sqlalchemy.ext.automap import automap_base 
from sqlalchemy.orm import Session, relationship 
from sqlalchemy import create_engine, Column, String 

Base = automap_base() 

engine = create_engine("postgresql://user:[email protected]:5432/mydb") 

# pre-declare User for the 'user' table 
class User(Base): 
    __tablename__ = 'user' 

    # override schema elements like Columns 
    oname = Column('originalname', String) 

    # and a relationship. I name it 'weird' because in my database schema 
    # this relationship makes absolutely no sense, but it does demonstrate 
    # the point 
    weird = relationship("usergroup", 
         foreign_keys='usergroup.id', 
         primaryjoin='and_(usergroup.id==User.id)') 

Base.prepare(engine, reflect=True) 
session = Session(engine) 

# Test this by querying the User table and then following the relationship 
u = session.query(User).filter(User.oname == 'testuser').one() 
print (u.oname) 
for g in u1.weird: 
    print g.name 

Vedi qui per la documentazione (tra cui un altro esempio): http://docs.sqlalchemy.org/en/latest/orm/extensions/automap.html?highlight=automap#specifying-classes-explicitly

Problemi correlati