I'm trying to serialize the result (a list) of an sqlalchemy query to json.
this is the class:
class Wikilink(Base):
__tablename__='Wikilinks'
__table_args__={'extend_existing':True}
id = Column(Integer,autoincrement=True,primary_key=True)
title = Column(Unicode(350))
user_ip = Column(String(50))
page = Column(String(20))
revision = Column(String(20))
timestamp = Column(String(50))
and I guess my problem is with the __repr__(self): function.
I tried something like:
return '{{0}:{"title":{1}, "Ip":{2}, "page":{3} ,"revision":{4}}}'.format(self.id,self.title.encode('utf-8'),self.user_ip,self.page,self.revision)
or:
return '{"id"={0}, "title"={1}, "Ip"={2}}'.format(self.id,self.title.encode('utf-8'),self.user_ip.encode('utf-8'),self.page,self.revision)
and I got:
TypeError(repr(o) + " is not JSON serializable")
ValueError: Single '}' encountered in format string
I tried:
return '{id=%d, title=%s, Ip=%s}'%(self.id,self.title.encode('utf-8'),self.user_ip.encode('utf-8'))
and I got:
TypeError: {id=8126, title=1 בדצמבר, Ip=147.237.70.106} is not JSON serializable
adding "" around (according to the JSON formatting) like this: "id"="%d", "title"="%s", "Ip"="%s" didn't help either.
I know this is supposed to be dead simple but I just can't get this right
actually bottle is handling the jsonification part automatically, but trying to call json.dumps on the result gives me the same errors.
Instead of trying to convert to json a string, you could define, for example, your own to_dict method that returns the dictionary structure it seems you're trying to create and, after that, generate the json from that structure:
>>> import json
>>> d = {'id':8126, 'title':u'1 בדצמבר', 'ip':'147.237.70.106'}
>>> json.dumps(d)
'{"ip": "147.237.70.106", "id": 8126, "title": "1 \\u05d1\\u05d3\\u05e6\\u05de\\u05d1\\u05e8"}'
I'm not sure I understand what you tried. Couldn't you build the dict and let json.dumps() do the work for you?
Something like:
>>> class Foo:
... id = 1
... title = 'my title'
... to_jsonize = ['id', 'title']
>>>
>>> dct = {name: getattr(Foo,name) for name in Foo.to_jsonize}
>>> import json
>>> json.dumps(dct)
'{"id": 1, "title": "my title"}'
Related
I have a Pydantic model defined as follows:
class IntOrString(BaseModel):
int_value: Optional[StrictInt] = None
string_value: Optional[StrictStr] = None
Is there a way I can customize json() to make the output as follows:
p = IntOrString(int_value=123)
print(p.json())
#> 123
p = IntOrString(string_value="Hello World")
print(p.json())
#> "Hello World"
Note: IntOrString can be a nested attribute of another Pydantic model.
In addition to object (e.g. {"id": 123}), string, number boolean are also valid JSON type. In other words, the question is can a pydantic model be serialized to string, number or boolean instead of object?
I know it's a weird requirement. Just want to know if that's possible.
Thank you.
For such a simple thing as excluding None-valued fields in the JSON representation, you can simply use the built-in exclude_none parameter:
from typing import Optional
from pydantic import BaseModel, StrictInt, StrictStr
class Dummy(BaseModel):
id: Optional[StrictInt] = None
name: Optional[StrictStr] = None
class Other(BaseModel):
dummy: Dummy
if __name__ == '__main__':
p = Dummy(id=123)
print(p.json(exclude_none=True))
p = Dummy(name="Hello World")
print(p.json(exclude_none=True))
o = Other(dummy=Dummy(id=123))
print(o.json(exclude_none=True))
Output:
{"id": 123}
{"name": "Hello World"}
{"dummy": {"id": 123}}
If you want more complex stuff, you may want to provide your own custom JSON encoder either via the encoder parameter on a call-by-call basis or in the model config via json_dumps or json_encoders.
I am new to Python. I have been trying to parse the response sent as parameter in a function.
I have been trying to convert a function from Perl to Python.
The Perl block looks something like this:
sub fetchId_byusername
{
my ($self,$resString,$name) =#_;
my $my_id;
my #arr = #{$json->allow_nonref->utf8->decode($resString)};
foreach(#arr)
{
my %hash = %{$_};
foreach my $keys (keys %hash)
{
$my_id = $hash{id} if($hash{name} eq $name);
}
}
print "Fetched Id is : $my_id\n";
return $my_id;
The part where JSON data is being parsed is troubling me. How do i write this in python3.
I tried something like
def fetchID_byUsername(self, resString, name):
arr = []
user_id = 0
arr = resString.content.decode('utf-8', errors="replace")
for item in arr:
temp_hash = {}
temp_hash = item
for index in temp_hash.keys():
if temp_hash[name] == name:
user_id = temp_hash[id]
print("Fetched ID is: {}".format(user_id))
return user_id
Now I am not sure, if this is the right way to do it.
The json inputs are something like:
[{"id":12345,"name":"11","email":"11#test.com","groups":[{"id":6967,"name":"Test1"},{"id":123456,"name":"E1"}],"department":{"id":3863,"name":"Department1"},"comments":"111","adminUser":false},{"id":123457,"name":"1234567","email":"1234567#test.com","groups":[{"id":1657,"name":"mytest"},{"id":58881,"name":"Service Admin"}],"department":{"id":182,"name":"Service Admin"},"comments":"12345000","adminUser":true}]
Thanks in advance.
Your json input should be valid python I changed false to False and true to True. If it is json formatted string you can do
import json
data=json.loads(json_formatted_string_here) #data will be python dictionary herer
And tried like this it just iterates and when match found returns id
data=[{"id":12345,"name":"11","email":"11#test.com","groups":[{"id":6967,"name":"Test1"},{"id":123456,"name":"E1"}],"department":{"id":3863,"name":"Department1"},"comments":"111","adminUser":False},{"id":123457,"name":"1234567","email":"1234567#test.com","groups":[{"id":1657,"name":"mytest"},{"id":58881,"name":"Service Admin"}],"department":{"id":182,"name":"Service Admin"},"comments":"12345000","adminUser":True}]
def fetch_id_by_name(list_records,name):
for record in list_records:
if record["name"] == name:
return record["id"]
print(fetch_id_by_name(data,"11"))
First of all import the the json library and use json.loads() like:
import json
x = json.loads(json_feed) #This converts the json feed to a python dictionary
print(x["key"]) #values to "key"
In python, I receive JSON data. The data looks like the following stub:
{
"id": 1,
"naam": "4.13",
"ruimte_temperatuur_sensor": {...},
// etc
}
I map this json to an object (note the sensor is mapped already):
ruimte = Ruimte(id=id,
naam=naam,
ruimte_temperatuur_sensor=temperatuur_sensor,
ruimte_humiditeit_sensor=humiditeit_sensor,
ruimte_beweging_sensor=beweging_sensor,
airco_temperatuur_sensor=airco_sensor,
radiator_temperatuur_sensor=radiator_sensor)
The strangest thing happens:
The id field in JSON is an integer, but Python maps it to a tuple. In my debugger, you can clearly see that the id=id maps to an integer, but then all of a sudden my object contains a tuple:
The object's constructor should not cause that:
class Ruimte:
def __init__(self,
id: int,
naam: str,
ruimte_temperatuur_sensor: Sensor,
ruimte_humiditeit_sensor: Sensor,
ruimte_beweging_sensor: Sensor,
airco_temperatuur_sensor: Sensor,
radiator_temperatuur_sensor: Sensor):
self.id = id,
self.naam = naam,
self.ruimte_temperatuur_sensor = ruimte_temperatuur_sensor
self.ruimte_humiditeit_sensor = ruimte_humiditeit_sensor
self.ruimte_beweging_sensor = ruimte_beweging_sensor
self.airco_temperatuur_sensor = airco_temperatuur_sensor
self.radiator_temperatuur_sensor = radiator_temperatuur_sensor
In the sub-objects the id is not parsed to a tuple, for exampe ruimte.airco_temperatuur_sensor.id is an integer:
but that JSON is parsed the same way:
def _parse_json_to_sensor(self, json: dict) -> Sensor:
id = json["id"]
type = SensorType(json["type"])
meet_interval_sec = json["sensorInstelling"]["meetIntervalSec"]
opslaan_interval_sec = json["sensorInstelling"]["opslaanIntervalSec"]
sensor = Sensor(id=id,
type=type,
meet_interval_sec=meet_interval_sec,
opslaan_interval_sec=opslaan_interval_sec)
I'm totally lost on this. What could cause this?
You have commas after the lines where you assign self.id and self.naam. Remove them.
a_string = 'string',
type(a_string)
>>> tuple
The comma in the line:
self.id = id,
leads to the creation of a tuple. See this example:
a = 1
b = 1
c = 1,
print(b)
print(c)
I have some Data that I need to write to a JSON string.
I have it working with dict items but want to encompass it all in classes to help ensure the correct data.
The following code is a comparison between the dict items and the class item output. They don't match, and I can't figure out what I am missing.
I get a "bound method Event.encode of Event..." in my JSON string.
from collections import namedtuple
import json
class Event(namedtuple('Event', 'itemName, itemID')):
def encode(self):
obj = {}
obj['itemName'] = str(self.itemName)
obj['itemID'] = int(self.itemID)
return json.dumps(obj)
curEv = Event('MyName', 5)
print 'ClassEv : ', curEv.encode()
curEv2 = {'itemName':'MyName', 'itemID':5}
print 'DictEv : ', json.dumps(curEv2)
class Packet(namedtuple('Packet', 'pID, itemType, itemData')):
def encode(self):
obj = {}
obj['pID'] = int(self.pID)
obj['itemType'] = int(self.itemType)
obj['itemData'] = str(self.itemData.encode)
return json.dumps(obj)
packet = Packet(11, 0, curEv)
print 'ClassPacket: ', packet.encode()
packet2 = {'pID':11, 'itemType':0}
packet2['itemData'] = curEv2
print 'DictPacket : ', json.dumps(packet2)
You are failing to call the itemData.encode() function. Instead you are simply returning a reference to it.
Try:
obj['itemData'] = str(self.itemData.encode())
Note the extra () at the end.
I am using the following code to serialize my appengine datastore to JSON
class DictModel(db.Model):
def to_dict(self):
return dict([(p, unicode(getattr(self, p))) for p in self.properties()])
class commonWordTweets(DictModel):
commonWords = db.StringListProperty(required=True)
venue = db.ReferenceProperty(Venue, required=True, collection_name='commonWords')
class Venue(db.Model):
id = db.StringProperty(required=True)
fourSqid = db.StringProperty(required=False)
name = db.StringProperty(required=True)
twitter_ID = db.StringProperty(required=True)
This returns the following JSON response
[
{
"commonWords": "[u'storehouse', u'guinness', u'badge', u'2011"', u'"new', u'mayor', u'dublin)']",
"venue": "<__main__.Venue object at 0x1028ad190>"
}
]
How can I return the actual venue name to appear?
Firstly, although it's not exactly your question, it's strongly recommended to use simplejson to produce json, rather than trying to turn structures into json strings yourself.
To answer your question, the ReferenceProperty just acts as a reference to your Venue object. So you just use its attributes as per normal.
Try something like:
cwt = commonWordTweets() # Replace with code to get the item from your datastore
d = {"commonWords":cwt.commonWords, "venue": cwt.venue.name}
jsonout = simplejson.dumps(d)