Python 如何一次加载与SQLAlchemy中指定的对象相关的所有对象?
这是我数据库的简化项目 我的模型是由SQLAlchemy创建的,它看起来像这样Python 如何一次加载与SQLAlchemy中指定的对象相关的所有对象?,python,sqlalchemy,relationship,eager-loading,Python,Sqlalchemy,Relationship,Eager Loading,这是我数据库的简化项目 我的模型是由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
#!/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))
问题在于加载对象的时间。使用great,我得到了这个:
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)
有没有办法一次加载与book对象相关的所有内容?我尝试过使用session.refresh()对象,但它没有给出任何结果。您发布的代码只处理查询的结果—将sentense传递给函数。问题是默认情况下所有关系都是惰性的,因此它们需要更多的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()
#将sqlalchemy作为sa导入
sentense=sentense.query.options(sa.joinedload_all(
“单词、声音、单词、句子、书籍、作者”
),sa.联合加载所有(
“words.soundex.words.sentense.book.isbns”
)).filter().first()
请注意,这可能仍然非常缓慢,我不知道数据库和数据的详细信息,但这将导致一次发送一个大型查询
还请注意,您的代码还有其他问题。这种关系的“侧面”似乎是随机的,名字的多元化也不一致,这使得人们很难理解。在分析代码中,在for循环期间覆盖传入的sentense,因此sentense.id!=sentense.id
将始终计算False
。您还可以使用内部for循环中的word
覆盖外部for循环中的word