2016-09-26 46 views
-1

我有一個SQLAlchemy ORM,它的__str__()函數打印一個鍵和值的表。 下面的代碼其提交至數據庫並打印出來(屬性名稱更改爲清楚起見):SQLAlchemy:提交後的行爲不一致

user.some_attribute = <Some integer> 
session.add(user) 
session.commit() 
app.logger.debug("some_attribute is %s" % user.some_attribute) 
app.logger.debug("Created a DB row:\n%s" % user) 

這裏瘋狂的事情是,第二調試只打印工作,如果第一個調試的存在!

換句話說,如果存在兩個調試線,我得到:

some_attribute is 5 
+------------------------------------------+-------------------------------------------------+ 
| Field         | Value           | 
+------------------------------------------+-------------------------------------------------+ 
| creation_time       | 2016-09-26 15:25:45.630230      | 
| description        | Test Poly 835         | 
| destination_truck_ids     | ['A']            | 
| future_event_series_id     | None           | 
| id          | 1017           | 
... 

但如果只有第二個是現在,我得到:

+-------+-------+ 
| Field | Value | 
+-------+-------+ 
+-------+-------+ 

爲什麼會出現ORM沒有屬性,除非其特徵之一被打印?

+0

你是怎麼得到'__str__'來生成所有這些?在我的例子中,'str(user)'是我總是期望的:'__ main __。0x0000000003866FD0>的用戶對象'。 – zvone

回答

0

我發現了一種解決方法,即使我並不確定問題的性質。

報價the manual

默認情況下,會議還到期的所有 ORM管理屬性的事務之後提交的所有數據庫負載狀態。這樣後續操作就會從數據庫加載最新的數據。 此行爲可以使用sessionmaker或Session構造函數的expire_on_commit = False選項 禁用。

如果我使用expire_on_commit=False加載會話,問題就解決了 - 即使在提交之後,我也得到了ORM。

+0

這不是一種解決方法;這是IMO的正確解決方案。如果在提交後需要訪問實例的屬性而不再次加載,請關閉'expire_on_commit'。我相信這個功能在默認情況下是開啓的,因爲它使樸素的代碼工作。如果你知道你在做什麼,你可以簡單地關閉它。 – univerio

+0

這很好,除了打印一個ORM屬性導致它重新出現。 –