Pydantic - Find key in JSON File to use for object creation - pydantic

Is there any way to write a custom json fileparser for a pydantic class?
I have json files that have multiple objects configured in them and want to use the value of the objectname for the creation of the object.
// config.json
{
"object_type_1": {
"name" : "test1",
"value" : "mock",
},
"totally_different_object" : {
"color" : "blue",
"something" : "else",
}
I would like to write someting like
from pydantic import BaseModel
class ObjectType1(BaseModel):
name : str
value : str
object_typ_1_example = ObjectType1.parse_file("config.json", object_key = "object_type_1")
But I couldn't find any example

Related

Use null as default for a field in Avro4k

I am using avro4k and I have a field that is nullable, like this:
#Serializable
data class Product(
#AvroDefault("null")
#ScalePrecision(DEFAULT_SCALE, DEFAULT_PRECISION)
#Serializable(with = BigDecimalSerializer::class)
val price: BigDecimal? = null
)
This is the generated schema:
{
"type" : "record",
"name" : "Product",
"namespace" : "org.company",
"fields" : [ {
"name" : "ask",
"type" : [ {
"type" : "bytes",
"logicalType" : "decimal",
"precision" : 7,
"scale" : 2
}, "null" ],
"default" : "null"
} ]
}
Avro specification expects that null should not have the quotes.
I think it's also a problem that the null types appears last in the schema, according to the documentation:
Unions, as mentioned above, are represented using JSON arrays. For example, ["null", "string"] declares a schema which may be either a null or string.
(Note that when a default value is specified for a record field whose type is a union, the type of the default value must match the first element of the union. Thus, for unions containing “null”, the “null” is usually listed first, since the default value of such unions is typically null.)
Is there a way to fix both these issues?
You're supposed to use Avro.NULL in that case.
#Serializable
data class Product(
#AvroDefault(Avro.NULL)
#ScalePrecision(DEFAULT_SCALE, DEFAULT_PRECISION)
#Serializable(with = BigDecimalSerializer::class)
val price: BigDecimal? = null
)
It also fixes the order.

Karate - Conditional JSON schema validation

I am just wondering how can I do conditional schema validation. The API response is dynamic based on customerType key. If customerType is person then, person details will be included and if the customerType is org organization details will be included in the JSON response. So the response can be in either of the following forms
{
"customerType" : "person",
"person" : {
"fistName" : "A",
"lastName" : "B"
},
"id" : 1,
"requestDate" : "2021-11-11"
}
{
"customerType" : "org",
"organization" : {
"orgName" : "A",
"orgAddress" : "B"
},
"id" : 2,
"requestDate" : "2021-11-11"
}
The schema I created to validate above 2 scenario is as follows
{
"customerType" : "#string",
"organization" : "#? response.customerType=='org' ? karate.match(_,personSchema) : karate.match(_,null)",
"person" : "#? response.customerType=='person' ? karate.match(_,orgSchema) : karate.match(_,null)",
"id" : "#number",
"requestDate" : "#string"
}
but the schema fails to match with the actual response. What changes should I make in the schema to make it work?
Note : I am planning to reuse the schema in multiple tests so I will be keeping the schema in separate files, independent of the feature file
Can you refer to this answer which I think is the better approach: https://stackoverflow.com/a/47336682/143475
That said, I think you missed that the JS karate.match() API doesn't return a boolean, but a JSON that contains a pass boolean property.
So you have to do things like this:
* def someVar = karate.match(actual, expected).pass ? {} : {}

jackson json JsonIgnoreProperties and DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES do not work for non string fields

I have a Map fields in json file
"companyAddress" : {
"street1" : "99 test Ct",
"postalCode" : "95050",
"city" : "Santa Clara",
"state" : "CA",
"country" : "USA"
}
If my object does not have this field it throws com.fasterxml.jackson.databind.exc.MismatchedInputException","error.message":"Cannot deserialize instance of `java.lang.String` out of START_OBJECT
I tried #JsonIgnoreProperties(ignoreUnknown = true) class level annotation
as well as mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
The ignore field works only for String fields.
In fact for String fields no setting is required they are ignored if not present in class.
I am using jackson 2

Deserialize Mantle object using two JSON formats

Is there a way to construct a mantle object using two different JSON objects? For example, say there is an Address class and the following two JSON formats:
{
"street: "s",
"city" : "city",
"state" : "state",
"zipcode" "12345"
}
{
"street_one: "s1",
"street_two: "s2",
"apartment" : "apt 1",
"city" : "city",
"state" : "state",
"zip" "12345"
}
[MTLJSONAdapter modelOfClass:[Address class] fromJSONDictionary:JSONDictionary error:&error];
Is there somewhere in MTLJSONAdapter to recognize two formats and assign or serialize properties based on them?
+ (NSDictionary *)JSONKeyPathsByPropertyKey
{
if (isJsonV2) {
// do new mapping
}
else {
// do original mapping
}
}
Hope to do something like above, or anything that allows conditionally mapping to the object.
Mantle doesn't support this, but you could use a subclass for V2 which has the extra street entry, or use a protocol to encapsulate the shared behaviour.

Two "id" fields in one MongoDB collection with Rails 3?

I've got a Rails 3.0.9 project using the latest version of MongoDB and Mongoid 2.2.
I imported a CSV with an "id" field into a MongoDB collection named College, resulting in a collection like so:
{ "_id" : ObjectID("abc123"), "id" : ######, ... }
Observations:
The show action results in a URL utilizing the ObjectID
Displaying 'college.id' in index.html.erb displays the ObjectID
Questions:
How do I use the original "id" field as the parameter
Is "id" reserved by MongoDB, meaning I need to rename the "id" field in the
College collection (perhaps to "code") - if so, how?
Thanks!
Update
Answer:
db.colleges.update( { "name" : { $exists : true } } , { $rename : { "id" : "code" } }, false, true )
I used "name" since that was a field I could check for the existence.
_id is a reserved and required property in MongoDB - I think mongoid is mapping id to _id since that makes sense. There might be a way to access the id property through mongoid but I think you are much better off renaming the id column to something else to avoid confusion in the future.
{ $rename : { old_field_name : new_field_name } }
will rename the field name in a document (mongo 1.7.2+).
so
db.college.update({ "_id" : { $exists : true }}, { $rename : { 'id' : 'code' } }, false, true);
should update every record in that collection and rename the id field to code.
(obviously test this before running in any important data)