-
Notifications
You must be signed in to change notification settings - Fork 144
RUST-1899 Deserialization with UUID #467
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
example of data currently in mongodb
|
Hi @Bryson14, thanks for this detailed report! We do indeed have a bug in our deserialization logic for UUIDs that are not in binary format. I made a PR to fix this (#468), so we'll put out a patch release once that's approved and merged. Once the fix is in, your UUID deserialization from strings when using the I was unable to reproduce the compilation errors you're encountering. Are you seeing those errors with the |
I think the |
I'll give the feature flags a try again. For the bson::uuid, it was too much time dealing with it that I just went with treating the data from the database as strings (which they are strings from the migration). I would have to change the rust code and database UUIDs to deal with this right now and I don't see any good benefit from using bson::uuid at the moment. Perhaps performance? |
It depends upon your use case. If you're just reading your data via the driver then it likely doesn't matter much which type you're using, but I'm going to close this out since the fix in #468 has been released, but feel free to create another issue if you have any further feedback or questions! |
Hi @isabelatkinson, we hit the same problem when trying to deserialize a string _id field using this newtype: #[derive(Clone, PartialEq, Eq, Debug, Hash, Serialize, Ord, PartialOrd, Deserialize, Display, Default, Copy)]
pub struct UserId(uuid::Uuid); We are inserting data like this: doc! {
"_id": "021afc11-2771-44c8-8b61-e17c3d4b2685",
...
} We receive this error:
Unfortunately, we cannot easily use the Manually implementing impl<'de> Deserialize<'de> for UserId {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct UserIdVisitor;
impl<'de> Visitor<'de> for UserIdVisitor {
type Value = UserId;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("a UUID string")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
Uuid::parse_str(value).map(UserId).map_err(de::Error::custom)
}
}
deserializer.deserialize_str(UserIdVisitor)
}
} or we could add |
Hi @FalkWoldmann, would it be possible for you to use the #[derive(Debug, Deserialize)]
struct UserId(bson::Uuid);
#[derive(Debug, Deserialize)]
struct Data {
#[serde(rename = "_id")]
id: UserId,
}
#[tokio::main]
async fn main() -> mongodb::error::Result<()> {
let uuid = uuid::Uuid::new_v4();
let document = doc! {
"_id": uuid.to_string(),
};
let client = Client::with_uri_str("<uri str>").await?;
let collection = client.database("db").collection("coll");
collection.insert_one(document).await?;
let collection = collection.clone_with_type::<Data>();
let document = collection.find_one(doc! {}).await?.unwrap();
// requires uuid-1 feature flag enabled for the bson crate
assert_eq!(document.id.0.to_uuid_1(), uuid);
Ok(())
} We can also consider adding a helper to
We can certainly add more trait impls to |
Unfortunately, we store our data _ids in String format and it is not feasible to migrate the field to bson anytime soon and as far as I understood (please correct me if I'm wrong), we cannot just use bson::Uuid in our code in this case. Having some For |
Versions/Environment
cargo pkgid mongodb
&cargo pkgid bson
) 2.9.0 & 2.8.2db.version()
) 7.2.0Describe the bug
A clear and concise description of what the bug is.
I am migrating data from another database which includes UUIDs stored as strings. I understand that bson::uuid stores data as binary base-64 data with a subtype flag = 4, however my current database is using strings and the rust code interacting with it is expected deserialization to and from strings.
My current struct definition:
When I run
find()
to get items from this collection I get,I tried to remedy this by changed
uuid::Uuid
in the struct definition tobson::Uuid
but got a similar error:Trying to use the serde_with-3 flag didn't help and I actually got compiler errors. This was after adding the feature flag with
cargo add bson -F serde_with-3
. The documentation didn't say that I had to add other dependancies to get this to work.what to do:
So I'm thinking there are two fixes to this. Either I fix this issue in code and get the serialization and deserialization to play well with uuid::Uuid, or I migrate all the fields that contain string uuid in the db to Mongo's UUID format. In that case, I'd appreciate any tools to do that, but might just have to bite the bullet and write a small python scipt to do that.
To Reproduce
Cargo.toml
The text was updated successfully, but these errors were encountered: