-
Notifications
You must be signed in to change notification settings - Fork 1.8k
feat(firestore): add PyMongo duck-typing serialization support #18406
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鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -214,6 +214,32 @@ def encode_value(value) -> types.document.Value: | |
| if isinstance(value, _BSONType): | ||
| return encode_value(value._to_map_value()) | ||
|
|
||
| # Duck-type native PyMongo / third-party BSON objects | ||
| if hasattr(value, "__class__"): | ||
| cls_name = value.__class__.__name__ | ||
| if cls_name == "ObjectId" and hasattr(value, "binary"): | ||
| return encode_value({"__oid__": str(value).lower()}) | ||
| if cls_name == "Decimal128" and hasattr(value, "to_decimal"): | ||
| return encode_value({"__decimal128__": str(value)}) | ||
| if cls_name == "Regex" and hasattr(value, "pattern"): | ||
| opts = getattr(value, "flags", "") or getattr(value, "options", "") | ||
| return encode_value( | ||
| {"__regex__": {"pattern": value.pattern, "options": str(opts)}} | ||
| ) | ||
| if cls_name == "Timestamp" and hasattr(value, "time") and hasattr(value, "inc"): | ||
| return encode_value( | ||
| { | ||
| "__request_timestamp__": { | ||
| "seconds": value.time, | ||
| "increment": value.inc, | ||
| } | ||
| } | ||
| ) | ||
| if cls_name == "MinKey": | ||
| return encode_value({"__min__": None}) | ||
| if cls_name == "MaxKey": | ||
| return encode_value({"__max__": None}) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of encoding all of these special strings here, we should be able to rely on the BSONType class, which has this knowledge built in already. We should have a simple way to find the matching BSONType for this PyMongo class, and a simple way to convert any BSONType to a Value. Then we can just string it together as something like |
||
|
|
||
| if isinstance(value, GeoPoint): | ||
| return document.Value(geo_point_value=value.to_protobuf()) | ||
|
|
||
|
|
||
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.
The
encode_valuefunction is a critical hot path called recursively for every field of every document during serialization. While the proposed change aims to optimize standard types using an O(1) set lookup, any changes to this performance-critical code path must be validated and benchmarked to ensure they do not degrade performance or eliminate fast-path optimizations (such as the overhead of doublegetattrcalls). Please run benchmarks to verify the performance impact of this change.References