2013-06-28 3 views
0

이것은 내 데이터베이스의 단순화 된 프로젝트입니다.SQLAlchemy에 지정된 것과 관련된 모든 객체를 한꺼번에로드하는 방법은 무엇입니까?

enter image description here

내 모델은 SQLAlchemy의에 의해 만들어지고이 문제는 개체 로딩 시간 함께이

#!/usr/bin/python 

class Book(Base): 
    id = Column(Integer, primary_key = True) 
    title = Column(Unicode(512)) 
    sentenses = relationship("Sentense", backref = backref("book", uselist = False)) 
    isbns = relationship("ISBN", secondary = books_isbns, backref = "book") 
    authors = relationship("Author", secondary = books_authors, backref = "book") 

class Sentense(Base): 
    id = Column(Integer, primary_key = True) 
    content = Column(Unicode(512)) 
    words = relationship("Word", secondary = sentenses_words, backref = "sentense") 

class Word(Base): 
    id = Column(Integer, primary_key = True) 
    content = Column(Unicode(32), index = True, unique = True) 
    soundex_id = Column(Integer, ForeignKey('Soundex.id')) 

class Soundex(Base): 
    id = Column(Integer, primary_key = True) 
    code = Column(Unicode(5), index = True, unique = True) 
    words = relationship("Word", backref = backref("soundex", uselist = False)) 

처럼 보인다. 사용 큰이있어 I profiler :

Line #  Hits   Time Per Hit % Time Line Contents 
============================================================== 
    111            @staticmethod 
    112            @profile 
    113            def getBooksWithSimilarWordsLikeInThisSentence(session, sentense): 
    114  16   51  3.2  0.0   s = set() 
    115  89  116294 1306.7  0.1   for word in sentense.words: 
    116  4200  712414 169.6  0.5    for word in word.soundex.words: 
    117  33690  13370590 396.9  8.7     for sentense in word.sentense: 
    118  29563  130437  4.4  0.1      if sentense.id != sentense.id: 
    119  18732  44930792 2398.6  29.3       s.add(sentense.book) 
    120           
    121  16   709  44.3  0.0   list_of_other_books = list(s) 
    122           
    123 
    124  18748  25865  1.4  0.0   for book in list_of_other_books: 
    125 
    126  39016  48461924 1242.1  31.6    for authors in book.authors: 
    127  20284  564884  27.8  0.4     print authors.name 
    128           
    129  33896  44392639 1309.7  29.0    for isbn in book.isbns: 
    130  15164  421289  27.8  0.3     print isbn.raw 
    131           
    132  18732  133320  7.1  0.1    books.add(book) 
    133           
    134  16   926  57.9  0.0   return list(books) 

한 번에 개체를 예약 할 관련된 모든 내용을로드 할 수있는 방법이 있나요를? session.refresh() 객체를 사용하려고했지만 결과가 없습니다.

답변

2

게시 한 코드는 쿼리의 결과만을 처리합니다. 문장을 함수에 전달합니다. 문제는 모든 관계가 기본적으로 게으르기 때문에 더 많은 SQL 쿼리가 필요하므로 느려질 수 있습니다.

해결책은 원하는 모든 관계를 열망하는 것입니다. 이 여전히 매우 느릴 수

# import sqlalchemy as sa 
sentense = Sentense.query.options(sa.joinedload_all(
     "words.soundex.words.sentense.book.authors" 
    ), sa.joinedload_all(
     "words.soundex.words.sentense.book.isbns" 
    )).filter(<some filters here>).first() 

주, 나는 데이터베이스 및 데이터의 세부 사항을 모르겠지만, 한 번에 보내지고 하나 개의 큰 쿼리가 발생합니다 : 이런 식으로 뭔가가 당신을 얻을 것이다.

또한 코드에 다른 문제가 있습니다. 관계의 "측면"은 무작위로 보이고 이름의 복수화는 일관성이 없으므로 따르기가 어렵습니다. 프로파일 링 된 코드에서 for 루프 중에 전달 된 문장을 덮어 쓰므로 sentense.id != sentense.id은 항상 False을 평가합니다. 또한 내부 루프의 word으로 외부 for 루프에서 word을 덮어 씁니다.