2015-04-17 192 views
3

我一直在冒險嘗試讓分數時間分辨率在我的數據庫中正常工作的奧德賽。我使用python方法datetime.now()來創建日期對象。然後我將這些對象存儲在映射到來自SqlAlchemy庫的COLUMN(DATETIME(9))的字段中。最初,我得到一個錯誤,我的數據被截斷。這是因爲我使用的是MySQL 5.5。我已經更新到5.6.19,不再收到數據截斷錯誤。SqlAlchemy mysql毫秒或微秒精度

但是,數據庫仍然不包含小數時間條目。例如,這裏指的是從datetime.now()對象實例化值:

2015-04-17 16:31:12.804444 

以上正是我所期望的。內存中的對象具有微秒的分辨率。現在,它保存這mysql數據庫後,我看到了下面的值,如果我打開mysql命令行客戶端,並使用select語句返回該行:

2015-04-17 16:31:13 

顯然,值被四捨五入到最接近第二。這很糟糕,我不知道是什麼原因造成的!

如果它是相關的,我使用的MySQL連接器的Python 2.0.3 ==

更新: 我也嘗試過使用COLUMN(DATETIME(6)),但得到了同樣的行爲。

我下面,包括型號,萬一這些信息是相關的:

class User(Base): 
     __tablename__ = 'Users' 

     uid = Column(INT, primary_key=True, autoincrement=True) 
     dateCreated = Column(DATETIME(6)) 

     def __init__(self, *args, **kwargs): 
       super(user, self).__init__(*args, **kwargs) 
       self.dateCreated = datetime.now() 

UPDATE: 佩德羅的建議是沒有問題的,但它確實幫助我取得進步,所以非常感謝。我嘗試在sql連接器中單步執行代碼,直到遇到mysql插入語句。該聲明確實包含分數時間值。但是,執行時,該值將被舍入。當我在桌子上做一個描述時,我注意到日期時間類型就是這樣,datetime當它真的應該是datetime(6)

我正在使用SA模型生成數據庫本身,SA模型明確聲明瞭Column(DATETIME(6))Base.metadata.create_all(self.db, checkfirst=True),所以我不明白爲什麼(6)沒有在實際的表結構中結束。我想我會盡快弄清楚,我會在發佈時更新。

更新: DATETIME的構造函數不接受字段長度規範。它只需要時區的參數。我不清楚如何指定日期時間字段的長度,因爲像varchar這樣的類型可以將它傳遞給構造函數。潛水繼續。

+0

當你選擇返回到Python的值時,你會「結束了這個」?用'mysql'命令行工具或一些GUI工具查看它們? – abarnert

+0

此外,根據[文檔](https://dev.mysql.com/doc/refman/5.7/en/fractional-seconds.html),「fsp值,如果給出,必須在0到6.值爲0表示沒有小數部分,如果省略,則默認精度爲0.「那麼,你確定'DATETIME(9)'不把9視爲「不在0到6的範圍內,忽略並使用默認值(它是0)」嗎? – abarnert

+0

另外,您可以使用其他工具以微秒插入值嗎?這將有助於排除mysql-connector-python問題出在哪一邊...... – abarnert

回答

12

我遇到的問題是股票SqlAlchemy DATETIME類不能用於將(6)值傳遞給構造函數以表示分數時間值的mysql要求。相反,需要使用sqlalchemy.dialects.mysql.DATETIME類。這個類允許使用fsp參數所以,一列聲明實際上應該看起來像(小數秒參數。):

dateCreated = Column(DATETIME(fsp=6)) 

感謝那些人誰回答。它有助於指導我的調查,最終絆倒這個深奧且非常混亂的區別。

+0

參考文檔:http://docs.sqlalchemy.org/en/latest/dialects/mysql.html ;搜索'sqlalchemy.dialects.mysql.DATETIME' – mraxus

0

根據該MySQL documentation,它只支持精確到6位(微秒):

「的MySQL 5.6.4和向上擴展了TIME,DATETIME和時間戳值分數秒支撐,具有高達微秒( 6位數字)精度「

我不確定,但指定9位數字可能會將列恢復爲較小的默認精度。