-
Notifications
You must be signed in to change notification settings - Fork 266
Expose Avro reader to PyIceberg #1328
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
base: main
Are you sure you want to change the base?
Conversation
// I don't fully comprehend the deserializer here, | ||
// it works for a Type, but not for a StructType | ||
// So I had to do some awkward stuff to make it work | ||
let res: Result<Type, _> = serde_json::from_str(json); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have an example of the JSON input that fails deserialization into a StructType? If so I'll see what I can do
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @sdd for jumping in here 👍
I would expect the following to work:
let res: Result<Type, _> = serde_json::from_str(json); | |
let res = serde_json::from_str<StructType>(json); |
I was also able to reproduce this in a unit test:
#[test]
fn empty_struct_type() {
let json = r#"{"type": "struct", "fields": []}"#;
let expected = StructType {
fields: vec![],
id_lookup: OnceLock::default(),
name_lookup: OnceLock::default(),
};
let res = serde_json::from_str::<StructType>(json).unwrap();
assert_eq!(res, expected);
}
But it looks like we need to wrap it in the Type
enum.
Hi @Fokko, I experimented a bit with this PR. One possible approach is to allow Python to access our structs in We could have something like this: #[pyfunction]
pub fn read_manifest_list_v2(bs: &[u8]) -> PyManifestList {
let reader = apache_avro::Reader::new(bs).unwrap();
let values = apache_avro::types::Value::Array(
reader
.collect::<std::result::Result<Vec<apache_avro::types::Value>, _>>()
.unwrap(),
);
let manifest_list = apache_avro::from_value::<_serde::ManifestListV2>(&values).unwrap();
PyManifestList {
inner: manifest_list,
}
} Or much better if we can expose such API directly: #[pyfunction]
pub fn read_manifest_list_v2(bs: &[u8]) -> PyManifestList {
PyManifestList {
inner: ManifestList::parse_as_is(bs),
}
} Our current design focuses solely on Rust users, but some users may simply want to parse the file themselves and don’t want iceberg-rust to handle any transformation (such as parsing into We could reconsider this, perhaps we can expose these as a public API, but hide them behind a feature gate. cc @liurenjie1024 and @sdd for ideas. |
Yes, that makes sense to me. I think we still want to have Iceberg-Rust some things like setting the default values for V2 (eg, setting Apart from that, I think your approach is great. Curious to learn what others think. |
pub struct PyLiteral { | ||
inner: Literal, | ||
} | ||
|
||
|
||
#[pyclass] | ||
pub struct PyPrimitiveLiteral { | ||
inner: PrimitiveLiteral, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we consider having a values.rs
module like what we did in core crate?
I'm leaning toward to this approach, also this makes the api more aligned with python/java implementation. |
Thanks everyone for chiming in here. Let me summarize the discussion. I think there is consensus that the callback is not ideal.
I'm leaning towards 2 since that aligns the best with PyIceberg, where we can deserialize the manifest-list without having to know about the schema. I would make sure that we have consensus before moving into a certain direction, and happy to follow up on that. |
+1 |
I like #2 as well. The refactor should be less effort than scaffolding between python class and rust struct |
## Which issue does this PR close? I would like to invite everyone to roast my Rust-skills in order for me to improve myself :) Unblocks #1328 This aligns closely with PyIceberg and Java and greatly simplifies the use of the Avro readers in PyIceberg. Otherwise, we would need to update public APIs. ## What changes are included in this PR? ## Are these changes tested? --------- Co-authored-by: Kevin Liu <[email protected]>
#1369 has been merged, maybe we can remove the callback now. |
Which issue does this PR close?
I've been looking into exposing the Avro readers to PyIceberg. This will give a huge benefit to PyIceberg because we can drop the Cython Avro reader.
What changes are included in this PR?
Exposing methods and structures to read the manifest lists, and manifests itself.
Are these changes tested?
By using them in PyIceberg :)