单元测试读取数据库时抛出SingleValueContainer错误求助
解决读取数据库时的「decoding a single value container is not supported」错误
问题场景
单元测试中已成功向数据库写入AddressTypeTwo记录,但调用get方法读取时,抛出「decoding a single value container is not supported」错误。相关代码如下:
Codable结构体定义
struct AddressTypeTwo: Codable { // MARK: CRUD var id: Int? var created: Date? var createdBy: String? var modified: Date? var modifiedBy: String? var deleted: Date? var deletedBy: String? var name: String? var companyId: Int? // MARK: CodingKeys enum CodingKeys: String, CodingKey { case id, created, createdBy, modified, modifiedBy case deleted, deletedBy case name case companyId = "company_id" } }
插入函数(运行正常)
func insert(toBeInserted obj: Codable) -> Int { if let newId = try? DbSupport.shared.activeDatabase?.run(table.insert(obj)) { return Int(newId) } return -1 }
触发错误的读取函数
func get<T: Codable>(_ includeDeleted: Bool = false) -> [T]? { var query = table.filter(tableDeleted == nil) if includeDeleted { query = table } guard let database = DbSupport.shared.activeDatabase else { return nil } let addresses: [T?]? = try? database.prepare(query).map { row in if let rowData: T = try? row.decode() { return rowData } return nil } return addresses?.compactMap { $0 } }
问题原因
错误的核心是row.decode()调用未明确指定解码目标类型,导致数据库库的解码逻辑默认尝试将行数据解析为单个值类型(如Int、String),但我们需要解码的是复合结构的AddressTypeTwo,二者不匹配从而触发错误。
解决方案
修改读取函数中的解码逻辑,明确指定要解码的泛型类型T.self:
func get<T: Codable>(_ includeDeleted: Bool = false) -> [T]? { var query = table.filter(tableDeleted == nil) if includeDeleted { query = table } guard let database = DbSupport.shared.activeDatabase else { return nil } do { let addresses: [T] = try database.prepare(query).map { row in try row.decode(T.self) } return addresses } catch { print("读取解码失败:\(error)") return nil } }
额外检查点
- Date类型解码匹配:如果数据库中Date字段存储的是时间戳(而非ISO8601字符串),需要配置Decoder的
dateDecodingStrategy,确保与存储格式一致。例如:
let decoder = JSONDecoder() decoder.dateDecodingStrategy = .secondsSince1970 // 可根据实际存储格式调整为.millisecondsSince1970或自定义策略
- 表字段与CodingKeys匹配:确认数据库表的所有字段(如
company_id)都存在,且数据类型与结构体属性对应(例如companyId是Int类型,表中字段也应为整数类型)。
内容的提问来源于stack exchange,提问作者iPhone Guy
相关产品推荐
相关产品推荐

