You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

postgres-kit能否将Swift Decimal类型编码存入PostgreSQL的numeric类型列?

完全不需要放弃基于Codable的自动增改语句生成能力,有两种成熟的方案可以解决Decimal编码的问题:

方案1:扩展Decimal遵守PostgresDataConvertible协议(最优方案)

PostgresKit的编码器会优先识别PostgresDataConvertible协议的实现,跳过默认的Encodable序列化逻辑,直接生成符合Postgres要求的参数格式,不需要修改原有模型的属性定义,全局生效。

import Foundation
import PostgresKit

extension Decimal: PostgresDataConvertible {
    public static var postgresDataType: PostgresDataType { .numeric }
    
    public init?(postgresData: PostgresData) {
        guard let value = postgresData.numeric else { return nil }
        self = value
    }
    
    public var postgresData: PostgresData? {
        .init(numeric: self)
    }
}

添加扩展后直接使用原有逻辑编码即可,生成的SQL中Decimal对应的值不会带引号,完全适配Postgres的numeric类型。

方案2:使用自定义属性包装器(适用于特定字段适配场景)

如果你只需要部分Decimal字段做特殊处理,或者需要基于通用SQLKit层做兼容,可以定义属性包装器,编码时直接输出SQLLiteral.numeric类型:

import Foundation
import SQLKit

@propertyWrapper
struct NumericField: Encodable {
    var wrappedValue: Decimal
    
    init(wrappedValue: Decimal) {
        self.wrappedValue = wrappedValue
    }
    
    func encode(to encoder: Encoder) throws {
        let numStr = wrappedValue.description
        try SQLLiteral.numeric(numStr).encode(to: encoder)
    }
}

// 模型中使用示例
struct Product: Codable {
    var id: UUID
    var name: String
    @NumericField var price: Decimal
    // 其他属性
}

以上两种方案都可以在保留Codable自动生成SQL能力的前提下,解决Decimal类型编码为带引号字符串的问题。

内容的提问来源于stack exchange,提问作者rj_code

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 12:27:00