10

Bắt đầu từ cơ sở dữ liệu hiện có (SQLite) có khóa ngoài, có thể SQLAlchemy tự động xây dựng relationships không?SQLAlchemy có thể tự động tạo các mối quan hệ từ lược đồ cơ sở dữ liệu không?

Lớp học SQLAlchemy được tạo tự động qua __table_args__ = {'autoload': True}.

Mục tiêu sẽ dễ dàng truy cập dữ liệu từ các bảng có liên quan mà không cần phải thêm tất cả các mối quan hệ một mình (tức là không sử dụng sqlalchemy.orm.relationship()sqlalchemy.orm.backref).

Trả lời

9

[Cập nhật] Kể từ SQLAlchemy 0.9.1 có Automap extension để thực hiện việc đó.

Đối với SQLAlchemy < 0.9.0, bạn có thể sử dụng phản xạ sqlalchemy.

SQL Phản chiếu của đối tượng tải các mối quan hệ khóa/khóa chính giữa các bảng. Nhưng không tạo ra mối quan hệ giữa các lớp được ánh xạ. Trên thực tế sự phản chiếu không tạo ra các lớp ánh xạ cho bạn - bạn phải chỉ định tên lớp được ánh xạ.

Thực ra tôi nghĩ rằng hỗ trợ phản chiếu để tải các khóa ngoại là công cụ trợ giúp và tiết kiệm thời gian tuyệt vời. Sử dụng nó, bạn có thể xây dựng một truy vấn bằng cách sử dụng tham gia mà không cần phải xác định cột nào để sử dụng cho một phép nối.

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 

Ngoài ra khi tôi đã sử dụng phản ánh để chạy các truy vấn cơ sở dữ liệu hiện có - tôi phải xác định tên lớp chỉ ánh xạ, bindings bảng, quan hệ, NHƯNG không có cần phải xác định các cột bảng cho những mối quan hệ.

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 

SQL tổng thểChú ý phản xạ là công cụ mạnh mẽ và tiết kiệm thời gian cho tôi, vì vậy, thêm quan hệ theo cách thủ công là chi phí nhỏ cho tôi.

Nếu tôi phải phát triển chức năng sẽ thêm mối quan hệ giữa các đối tượng được ánh xạ sử dụng các khóa ngoại hiện có, tôi sẽ bắt đầu sử dụng reflection with inspector. Sử dụng phương thức get_foreign_keys() cung cấp tất cả các thông tin cần thiết để xây dựng các mối quan hệ - gọi tên bảng, tên cột được đề cập và tên cột trong bảng đích. Và sẽ sử dụng thông tin này để thêm thuộc tính với mối quan hệ vào lớp được ánh xạ.

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']}] 
Các vấn đề liên quan