Odpowiedz

9

[Aktualizacja] Od SQLAlchemy 0.9.1 do tego jest Automap extension.

Dla SQLAlchemy < 0.9.0 możliwe jest użycie refleksji sqlalchemy.

Odbicie SQLAlchemy ładuje relacje kluczy obcych/kluczy podstawowych między tabelami. Ale nie tworzy relacji między odwzorowanymi klasami. W rzeczywistości odbicie nie tworzy odwzorowanych klas dla ciebie - musisz podać zmapowaną nazwę klasy.

Właściwie uważam, że obsługa refleksji przy ładowaniu kluczy obcych jest doskonałym pomocnikiem i narzędziem oszczędzającym czas. Za jego pomocą można zbudować zapytanie za pomocą sprzężeń, bez konieczności określania kolumn używanych do łączenia.

from sqlalchemy import * 
from sqlalchemy import create_engine, orm 
from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy.orm import relationship 



metadata = MetaData() 
Base = declarative_base() 
Base.metadata = metadata 

db = create_engine('<db connection URL>',echo=False) 
metadata.reflect(bind=db) 

cause_code_table = metadata.tables['cause_code'] 
ndticket_table = metadata.tables['ndticket'] 

sm = orm.sessionmaker(bind=db, autoflush=True, autocommit=True, expire_on_commit=True) 
session = orm.scoped_session(sm) 

q = session.query(ndticket_table,cause_code_table).join(cause_code_table) 
for r in q.limit(10): 
    print r 

Również kiedy przy użyciu odbicia do uruchamiania kwerend do istniejącej bazy danych - Musiałem określić tylko odwzorowanych klas nazwy, powiązania tabel, relacji, ale nie było potrzeby definiowania kolumn tabeli dla tych stosunków.

class CauseCode(Base): 
    __tablename__ = "cause_code" 

class NDTicket(Base): 
    __tablename__ = "ndticket" 
    cause_code = relationship("CauseCode", backref = "ndticket") 


q = session.query(NDTicket) 
for r in q.limit(10): 
    print r.ticket_id, r.cause_code.cause_code 

Ogólnie SQLAlchemy odbicie jest już potężnym narzędziem i zaoszczędzić mi czasu, więc dodanie relacji ręcznie to niewielki narzut dla mnie.

Gdybym musiał opracować funkcjonalność, która doda relacje między odwzorowanymi obiektami przy użyciu istniejących kluczy obcych, zacznę od używania reflection with inspector. Użycie metody get_foreign_keys() daje wszystkie informacje wymagane do zbudowania relacji - odesłaną nazwę tabeli, nazwę odnośnej kolumny i nazwę kolumny w tabeli docelowej. I użyłby tej informacji do dodania własności z relacją do zmapowanej klasy.

insp = reflection.Inspector.from_engine(db) 
print insp.get_table_names() 
print insp.get_foreign_keys(NDTicket.__tablename__) 
>>>[{'referred_table': u'cause_code', 'referred_columns': [u'cause_code'], 'referred_schema': None, 'name': u'SYS_C00135367', 'constrained_columns': [u'cause_code_id']}] 
Powiązane problemy