PowerSyncException:调用get() 时,查询未返回任何行
我正在把PowerSync集成到一个Android应用。启动应用时,我得到如下错误:
PowerSyncException: get() called with query that returned no rows
错误。仅此而已,它没有指向具体的文件或方法。我猜这个错误会涉及我所有的 powerSyncDatabase.get() 方法。下面是我如何使用 get() 方法的一个示例:
fun selectGoalById(id: UUID): Flow<Goal> {
return flow {
try {
val goal = dataSource.getDatabase().get(
sql = "SELECT * FROM goals WHERE id = ?",
parameters = listOf(id)
) { cursor ->
Goal(
id = UUID.fromString(cursor.getString("id")),
createdAt = cursor.getString("created_at"),
userId = UUID.fromString(cursor.getString("user_id")),
title = cursor.getString("title"),
priority = cursor.getString("priority").toInt()
)
}
emit(goal)
} catch (e: Exception) {
}
}
}
PowerSync数据库到现在确实应该是空的,那么我是否应该对查询返回结果采取不同的处理?
解决方案
文档指出,get 函数在“发生数据库错误或未找到结果”的情况下会抛出异常。所以看起来在给定的id下数据库中没有对应的Goal。
如果这是你的业务逻辑允许的,那么你应该把 get() 替换为 getOptional(),在未找到任何内容时它会返回 null,而不是抛出异常。
不过,值得怀疑的是你把结果包装在一个Flow中。Flow用于异步提供数据流。但你在Flow里只输出了一个单一的值。鉴于查询的“一次性”性质,在这里使用Flow似乎不太合适。若你确实希望在数据库有任何变化时得到通知,那么就需要重新执行查询。届时,Flow才合适,因为这个新结果也可以随后被输出到Flow中。
幸运的是,PowerSync已内置对这点的支持:
fun selectGoalById(id: UUID): Flow<Goal> = dataSource.getDatabase()
.watch(
sql = "SELECT * FROM goals WHERE id = ?",
parameters = listOf(id)
) { cursor ->
Goal(
id = UUID.fromString(cursor.getString("id")),
createdAt = cursor.getString("created_at"),
userId = UUID.fromString(cursor.getString("user_id")),
title = cursor.getString("title"),
priority = cursor.getString("priority").toInt(),
)
}
.map { it.single() }
函数 watch 返回一个包含所有结果的Flow(对于数据库的每一次变更,都会得到一个包含Goals的 List)。为了确保只返回一个单一的结果,随后会把这个Goals List映射成一个单独的Goal。这表示原本在没有找到任何Goal时应用崩溃的行为。如果你想改为返回 null,只需把 it.single() 替换为 it.firstOrNull(),并把函数的返回类型改为 Flow<Goal?>。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。