簡體   English   中英

在 sqlalchemy 中插入具有默認值列的行

[英]Insert a row with default value column in sqlalchemy

我正在編寫一個程序,它使用 sqlalchemy 作為客戶端的數據庫。

這是我的一張桌子

class DownloadRecord(Base):
    __tablename__ = "DownloadRecords"
    id = Column("Id", Integer, primary_key=True, autoincrement=True)

    download_name = Column("DownloadName", Unicode, nullable=False)
    download_date = Column(
        "DownloadDate", DateTime, default=datetime.datetime.utcnow, nullable=False
    )

download_date在此處和服務器端表中均使用默認值定義。 這是mssql服務器上列的定義

DownloadDate DATETIME NOT NULL DEFAULT GETDATE()

但是我嘗試添加記錄DownloadRecord(download_name="new_download_name")並且我得到以下異常。

sqlalchemy.exc.IntegrityError: (pyodbc.IntegrityError) ('23000', "[23000] [Microsoft][SQL Server Native Client 11.0][SQL Server]無法將值 NULL 插入到列 'DownloadReloadDownload'中列不允許空值。INSERT 失敗。(515) (SQLExecDirectW); [23000] [Microsoft][SQL Server Native Client 11.0][SQL Server]語句已終止。(3621)") [SQL: INSERT INTO [ DownloadRecords] ([DownloadName], [DownloadDate]) OUTPUT 插入。[Id] VALUES (?, ?)] [參數: ("new_download_name", None)]

我還嘗試使該列可以為空,但是當我添加新行時, DownloadDate列是 Null。 如何讓它自動使用默認值?

搜索我發現一些人使用server_default 參數修復。 但這使得數據庫服務器負責分配值。

download_date = Column(
    "DownloadDate", DateTime, server_default=text('NOW()'), nullable=False
)

另外根據SQLAlchemy 文檔,ColumnDefault class 是等效的,它也可以工作:

download_date = Column(
    "DownloadDate", DateTime, ColumnDefault(datetime.datetime.utcnow()), nullable=False
)

但是,這使用標量而不是可調用的。

希望它有效。

問題是列DownloadDate的類型與您在客戶端作為其默認值提供的值的類型之間不兼容。

您使用的類型是DateTime (在服務器端以及客戶端)。

但是,在以下代碼中:

Column("DownloadDate", DateTime, default=datetime.datetime.utcnow, nullable=False)

datetime.datetime.utcnow()的返回值是一個時區感知 object,而 SQL 服務器的DateTime不是。

我看到兩種可能的解決方案:

  1. 將默認值更改為可調用的,它返回不支持時區的datetime時間 object。

  2. DownloadDate列的類型更改為時區感知類型。 您可以在服務器端使用 SQL Server 的datetimeoffset ,在客戶端使用 SQLAlchemy 的DATETIMEOFFSET

查看Microsoft 關於日期和時間類型的文檔以獲取完整參考。

另一方面,考慮轉移到代碼優先設計,您可以在一個地方定義架構。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM