如何从仅返回 1 或 0 条记录的 Diesel 查询中获取 Option<T> 而不是 Option<Vec<T>>?
Posted
技术标签:
【中文标题】如何从仅返回 1 或 0 条记录的 Diesel 查询中获取 Option<T> 而不是 Option<Vec<T>>?【英文标题】:How do I get an Option<T> instead of an Option<Vec<T>> from a Diesel query which only returns 1 or 0 records? 【发布时间】:2018-02-28 02:05:30 【问题描述】:我正在查询名为messages
的表中的现有记录;此查询随后用作“查找或创建”功能的一部分:
fn find_msg_by_uuid<'a>(conn: &PgConnection, msg_uuid: &Uuid) -> Option<Vec<Message>>
use schema::messages::dsl::*;
use diesel::OptionalExtension;
messages.filter(uuid.eq(msg_uuid))
.limit(1)
.load::<Message>(conn)
.optional().unwrap()
我已将此设置为可选,因为在这种情况下,查找记录和不查找记录都是有效结果,因此此查询可能会返回一个 Vec
和一个 Message
或一个空的 Vec
,所以我总是最终检查Vec
是否为空或不使用这样的代码:
let extant_messages = find_msg_by_uuid(conn, message_uuid);
if !extant_messages.unwrap().is_empty() ...
然后如果它不是空的,则使用 Vec
中的第一个 Message
作为我找到的消息,使用类似
let found_message = find_msg_by_uuid(conn, message_uuid).unwrap()[0];
我总是取Vec
中的第一个元素,因为记录是唯一的,所以查询只会返回 1 或 0 条记录。
这对我来说有点乱而且似乎采取了太多步骤,我觉得好像有查询的记录那么它应该返回Option<Message>
而不是Option<Vec<Message>>
或None
如果没有记录匹配查询。
【问题讨论】:
你可能想使用first 【参考方案1】:如 cmets 中所述,使用 first
:
尝试加载单个记录。如果找到则返回
Ok(record)
,如果没有返回结果则返回Err(NotFound)
。如果查询确实是可选的,您可以在此结果上调用.optional()
以获取Result<Option<U>>
。
fn find_msg_by_uuid<'a>(conn: &PgConnection, msg_uuid: &Uuid) -> Option<Message>
use schema::messages::dsl::*;
use diesel::OptionalExtension;
messages
.filter(uuid.eq(msg_uuid))
.first(conn)
.optional()
.unwrap()
【讨论】:
以上是关于如何从仅返回 1 或 0 条记录的 Diesel 查询中获取 Option<T> 而不是 Option<Vec<T>>?的主要内容,如果未能解决你的问题,请参考以下文章