Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何一次加载与SQLAlchemy中指定的对象相关的所有对象?_Python_Sqlalchemy_Relationship_Eager Loading - Fatal编程技术网

Python 如何一次加载与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

这是我数据库的简化项目

我的模型是由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))
问题在于加载对象的时间。使用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