how to apply strptime(string,format) on StringProperty? - python

[solved]
i mixed up class method and instance method before. so when i
tried to call strptime(cls.ts,format) inside #classmethod function , i was actually calling
ts = ndb.StringProperty() or StringProperty('ts'),but
not the string value inside ts.
the correct one is to remove # decorator and call
strptime(self.ts,format) .
original question below
1:when the Token instance is created , init_created() is called to inititalize ts to a string.
2:user request the verification handler , with token as a arg , the token is used to retrieve
the Token instance.
3:i use the Token instance to call is_valid() .In is_valid , i convert ts back to datetime obj,
to compare to other datetime obj.
error 1 :
when i set( with the str() method )
delta = (now-datetime.strptime(str(cls.ts),'%Y-%b-%d / %H:%M:%S:%f')).total_seconds()
i get
ValueError: time data "StringProperty('ts')" does not match format '%Y-%b-%d / %H:%M:%S:%f'
error 2 :
so i try another way. i set (without str() )
delta = (now-datetime.strptime(cls.ts,'%Y-%b-%d / %H:%M:%S:%f')).total_seconds()
i get
TypeError: must be string, not StringProperty
so my question is how to correctly pass a stringproperty to strptime method.
thank you very much .
below is my code:
class Token(ndb.Model):
ts = ndb.StringProperty()
#classmethod
def init_created(cls):
ts = (datetime.utcnow() + timedelta(hours=8)).strftime(format='%Y-%b-%d / %H:%M:%S:%f')
return ts
#classmethod
def is_valid(cls):
now = (datetime.utcnow() + timedelta(hours=8))
delta = (now-datetime.strptime(cls.ts,'%Y-%b-%d / %H:%M:%S:%f')).total_seconds()
return (delta<expire_time)
class Verification(webapp2.RequestHandler):
def get(self , token ):
token_cls = Token.query(Token.token == token ).get()
if not (token_cls and token_cls.is_valid() ) :
template = jinja_environment.get_template('verification_error.html' )
pass
must be string, not StringProperty
Traceback (most recent call last):
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.1/webapp2.py", line 1536, in __call__
rv = self.handle_exception(request, response, e)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.1/webapp2.py", line 1530, in __call__
rv = self.router.dispatch(request, response)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.1/webapp2.py", line 1278, in default_dispatcher
return route.handler_adapter(request, response)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.1/webapp2.py", line 1102, in __call__
return handler.dispatch()
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.1/webapp2.py", line 572, in dispatch
return self.handle_exception(e, self.app.debug)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.1/webapp2.py", line 570, in dispatch
return method(*args, **kwargs)
File "/base/data/home/apps/s/1.374948928179626607/main.py", line 216, in get
if not (token_cls and token_cls.is_valid() ) :
File "/base/data/home/apps/s~/1.374948928179626607/main.py", line 86, in is_valid
delta = (now-datetime.strptime(cls.ts,'%Y-%b-%d / %H:%M:%S:%f')).total_seconds()
TypeError: must be string, not StringProperty

Your is_valid method shouldn't have the #classmethod decorator, as with it you're operating on the Token class, and not on the entity returned from your query. Once you've removed the decorator, it would be idiomatic to change cls to self.

Related

Odoo. TypeError: 'int' object is not iterable

I have problrem with my code.
class SiteTrip(models.Model):
_name = 'vips_vc.site_trip'
name = fields.Char()
session_ids = fields.One2many('vips_vc.session', 'site_trip_id', string='Session ID', index=True)
url_prevouse_ids = fields.Many2one('vips_vc.url_list', string='Prevouse URL', index=True)
url_current_ids = fields.Many2one('vips_vc.url_list', string='Current URL', index=True)
class URLList(models.Model):
_name = 'vips_vc.url_list'
name = fields.Char(string="URL", required=True)
url_parametes = fields.Char(string="URL parameters")
target_session_id = fields.One2many('vips_vc.session', 'target_url_ids', string='Target URL')
site_trip_prevouse_id = fields.One2many('vips_vc.site_trip', 'url_prevouse_ids', string='Prevouse URL')
site_trip_current_id = fields.One2many('vips_vc.site_trip', 'url_current_ids', string='Current URL')
remote_sites_id = fields.One2many('vips_vc.remote_sites', 'site_url_ids', string='Remote site page with URL')
remote_sites_target_url_id = fields.One2many('vips_vc.remote_sites', 'target_url_ids', string='URL on remote site page')
My controller:
def register_trip(self, currentURLid, prevouseURLid, sessionID):
currentURLid = int(currentURLid)
prevouseURLid = int(prevouseURLid)
result = None
### something
_logger.info("CREATE -----> session_ids: %r url_prevouse_ids: %r url_current_ids: %r",
sessionID, prevouseURLid, currentURLid)
result = table.create({'session_ids': sessionID, 'url_prevouse_ids': prevouseURLid,
'url_current_ids': currentURLid})
### something
return result.id
And error is:
2016-08-04 17:20:52,931 24261 INFO odoov8 openerp.addons.vips_vc.controllers: CREATE -----> session_ids: 59 url_prevouse_ids: 8 url_current_ids: 1
2016-08-04 17:20:52,938 24261 ERROR odoov8 openerp.http: Exception during JSON request handling.
Traceback (most recent call last):
File "/home/skif/odoo/openerp/http.py", line 540, in _handle_exception
return super(JsonRequest, self)._handle_exception(exception)
File "/home/skif/odoo/openerp/http.py", line 577, in dispatch
result = self._call_function(**self.params)
File "/home/skif/odoo/openerp/http.py", line 313, in _call_function
return checked_call(self.db, *args, **kwargs)
File "/home/skif/odoo/openerp/service/model.py", line 118, in wrapper
return f(dbname, *args, **kwargs)
File "/home/skif/odoo/openerp/http.py", line 310, in checked_call
return self.endpoint(*a, **kw)
File "/home/skif/odoo/openerp/http.py", line 806, in __call__
return self.method(*args, **kw)
File "/home/skif/odoo/openerp/http.py", line 406, in response_wrap
response = f(*args, **kw)
File "/home/skif/odoo/my-modules/vips_vc/controllers.py", line 194, in register_session
self.register_trip(currentURLid, prevouseURLid, sessionID)
File "/home/skif/odoo/my-modules/vips_vc/controllers.py", line 375, in register_trip
'url_current_ids': currentURLid})
File "/home/skif/odoo/openerp/api.py", line 266, in wrapper
return new_api(self, *args, **kwargs)
File "/home/skif/odoo/openerp/models.py", line 4094, in create
record = self.browse(self._create(old_vals))
File "/home/skif/odoo/openerp/api.py", line 266, in wrapper
return new_api(self, *args, **kwargs)
File "/home/skif/odoo/openerp/api.py", line 508, in new_api
result = method(self._model, cr, uid, *args, **old_kwargs)
File "/home/skif/odoo/openerp/models.py", line 4279, in _create
result += self._columns[field].set(cr, self, id_new, field, vals[field], user, rel_context) or []
File "/home/skif/odoo/openerp/osv/fields.py", line 795, in set
for act in values:
TypeError: 'int' object is not iterable
As you see when I'm trying to add record in vips_vc.site_trip i receive error. And error only for currentURLid. It has integer value. prevouseURLid has integer value too. prevouseURLid and currentURLid have similar relation One2Many/Many2One.
prevouseURLid is working. currentURLid isn't.
In this line I checked all param(logger output):
2016-08-04 17:20:52,931 24261 INFO odoov8 openerp.addons.vips_vc.controllers: CREATE -----> session_ids: 59 url_prevouse_ids: 8 url_current_ids: 1
url_prevouse_ids and url_current_ids have type is integer. They have defined value. They have similar relation. And insert url_current_ids return error.
Why is it happening?
Tomorrow all worked fine !
I did not touch relation. I did not touch type of variables...
UPD: After all manipulation I have this: If i'm trying to create record with any param (sessionID, prevouseURLid, currentURLid) I receiving same error: TypeError: 'int' object is not iterable
I found error.
I don't know how it working early...
result = table.create({'session_ids': sessionID, 'url_prevouse_ids': prevouseURLid,
'url_current_ids': currentURLid})
Here present ID record from other tables(models). When I removed all data (module was remove and install again).
After that step by step i check all data what received variables and stored in DB. I founded that vips_vc.url_list and vips_vc.session had not data.
after that i placed such code after create all records:
_logger.info(".....> Commit record ID %r", result.id)
table.env.cr.commit()
I have no idea why it code work early without commit().

Django model with embedded documents issues error: coercing to Unicode: need string or buffer, xxx found

I am trying to define models in Django with a list of embedded documents using mongoengine to connect to my mongodb data. Here is the relevant part of my models.py:
class Feature(EmbeddedDocument):
title = StringField(max_length=100, required=True)
is_property = BooleanField(default=True)
property_type = StringField(max_length=50, choices=PROPERTY_TYPE)
def __unicode__(self):
return self.title or u''
class Property(EmbeddedDocument):
feature = EmbeddedDocumentField(Feature)
value = StringField(max_length=2000, required=True)
def __unicode__(self):
return self.feature
class Concept(Document):
title = StringField(max_length=200, required=True)
properties = ListField(EmbeddedDocumentField(Property))
In console, when I try to create a new Concept, i do the following:
f = Feature(title='start time',property_type='Time')
p = Property(feature=f, value='6:30pm')
c = Concept(title='test', properties = [p])
c.save() #or c.properties[0]
I then get the following error:
c.properties
Out[36]: Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/IPython/core/interactiveshell.py", line 2731, in run_code
exec code_obj in self.user_global_ns, self.user_ns
File "<ipython-input-36-47a09d2ccd39>", line 1, in <module>
c.properties
File "/usr/lib/python2.7/dist-packages/IPython/core/displayhook.py", line 238, in __call__
format_dict = self.compute_format_data(result)
File "/usr/lib/python2.7/dist-packages/IPython/core/displayhook.py", line 150, in compute_format_data
return self.shell.display_formatter.format(result)
File "/usr/lib/python2.7/dist-packages/IPython/core/formatters.py", line 126, in format
data = formatter(obj)
File "/usr/lib/python2.7/dist-packages/IPython/core/formatters.py", line 447, in __call__
printer.pretty(obj)
File "/usr/lib/python2.7/dist-packages/IPython/lib/pretty.py", line 345, in pretty
return self.type_pprinters[cls](obj, self, cycle)
File "/usr/lib/python2.7/dist-packages/IPython/lib/pretty.py", line 529, in inner
p.pretty(x)
File "/usr/lib/python2.7/dist-packages/IPython/lib/pretty.py", line 360, in pretty
return _default_pprint(obj, self, cycle)
File "/usr/lib/python2.7/dist-packages/IPython/lib/pretty.py", line 480, in _default_pprint
p.text(repr(obj))
File "/usr/local/lib/python2.7/dist-packages/mongoengine-0.8.6-py2.7.egg/mongoengine/base/document.py", line 201, in __repr__
u = self.__str__()
File "/usr/local/lib/python2.7/dist-packages/mongoengine-0.8.6-py2.7.egg/mongoengine/base/document.py", line 212, in __str__
return unicode(self).encode('utf-8')
TypeError: coercing to Unicode: need string or buffer, Feature found
I think you need to explicitly convert the Feature to unicode, because mongoengine calls .encode on the __unicode__ of your object:
return unicode(self).encode('utf-8')
Where self is an instance of Property, and unicode(self) would return your Feature instance. So something like this should work
class Property(...):
# ...
def __unicode__(self):
return unicode(self.feature)

Google App Engine won't put object on server, but works on local version

I'm getting the following error on Google App Engine when I attempt to post a image (blob) and some other data to the datastore through a Web form. The code works on my local machine, but not when I upload to the GAE environment. :
<type 'str'> has type <type 'str'>, but expected one of: int, long, bool
Traceback (most recent call last):
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1535, in __call__
rv = self.handle_exception(request, response, e)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1529, in __call__
rv = self.router.dispatch(request, response)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1278, in default_dispatcher
return route.handler_adapter(request, response)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1102, in __call__
return handler.dispatch()
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 572, in dispatch
return self.handle_exception(e, self.app.debug)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 570, in dispatch
return method(*args, **kwargs)
File "/base/data/home/apps/s~mygrajj/1.371507856337629790/main.py", line 123, in post
car.put()
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/model.py", line 3232, in _put
return self._put_async(**ctx_options).get_result()
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/tasklets.py", line 325, in get_result
self.check_success()
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/tasklets.py", line 368, in _help_tasklet_along
value = gen.throw(exc.__class__, exc, tb)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/context.py", line 748, in put
key = yield self._put_batcher.add(entity, options)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/tasklets.py", line 371, in _help_tasklet_along
value = gen.send(val)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/context.py", line 280, in _put_tasklet
keys = yield self._conn.async_put(options, datastore_entities)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/datastore/datastore_rpc.py", line 1574, in async_put
pbs = [self.__adapter.entity_to_pb(entity) for entity in entities]
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/model.py", line 570, in entity_to_pb
pb = ent._to_pb()
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/model.py", line 2945, in _to_pb
prop._serialize(self, pb, projection=self._projection)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/model.py", line 1297, in _serialize
p.set_multiple(self._repeated or parent_repeated)
File "cpp_message.pyx", line 124, in cpp_message.SetScalarAccessors.Setter (third_party/apphosting/python/protobuf/proto1/cpp_message.cc:2229)
TypeError: <type 'str'> has type <type 'str'>, but expected one of: int, long, bool
When trying to execute the following code:
class AddCar(blobstore_handlers.BlobstoreUploadHandler, webapp2.RequestHandler):
def post(self):
car = Car()
if self.get_uploads('file'):
upload_files = self.get_uploads('file') # 'file' is file upload field in the form
blob_info = upload_files[0]
car.CarBlobKey = blob_info.key()
car.CarImageServingURL.append(images.get_serving_url(blob_info.key()))
car.CarYear = self.request.get('modelyear0')+self.request.get('modelyear1')+self.request.get('modelyear2')
car.CarMake = self.request.get('makeField')
car.CarModel = self.request.get('modelField')
car.CarPosterGrajjStatus = self.request.get('which_grajj')
if users.get_current_user():
car.CarPoster = users.get_current_user()
car.put()
#grajj_query = Car.query()
#cars = grajj_query.fetch(100)
self.redirect('/mygrajj.html')
Here's my model:
class Car(ndb.Model):
# Car class contains data on a prototype car
CarYear = ndb.StringProperty()
CarMake = ndb.StringProperty()
CarModel = ndb.StringProperty()
CarPoster = ndb.UserProperty()
CarPosted = ndb.DateTimeProperty(auto_now_add="true")
CarPosterGrajjStatus = ndb.StringProperty()
CarBlobKey = ndb.BlobKeyProperty(indexed="false")
CarImageServingURL = ndb.StringProperty(indexed="false", repeated="true")
The code works on my local machine, but not when it's deployed
How about drop the blob and isolate where the problem is.
I think this line will reference a NoneType since CarImageServingURL does not have a default value.
car.CarImageServingURL.append(images.get_serving_url(blob_info.key()))
You could rewrite it as
car.CarImageServingURL = images.get_serving_url(blob_info.key())
Or try changing the definition to have a default:
CarImageServingURL = ndb.StringProperty(indexed="false", repeated="true", default="")
you need to change all the parameter to Boolean
class Car(ndb.Model):
# Car class contains data on a prototype car
CarYear = ndb.StringProperty()
CarMake = ndb.StringProperty()
CarModel = ndb.StringProperty()
CarPoster = ndb.UserProperty()
CarPosted = ndb.DateTimeProperty(auto_now_add="true")
CarPosterGrajjStatus = ndb.StringProperty()
CarBlobKey = ndb.BlobKeyProperty(indexed="false")
CarImageServingURL = ndb.StringProperty(indexed="false", repeated="true")
auto_now_add=True
indexed=False
repeated=True
ommit the ""

SQLAlchemy __init__ not running

I have the following code:
session = scoped_session(sessionmaker(autocommit=False, autoflush=True, bind=engine))
Base = declarative_base()
Base.query = session.query_property()
class CommonBase(object):
created_at = Column(DateTime, default=datetime.datetime.now)
updated_at = Column(DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now)
class Look(Base, CommonBase):
__tablename__ = "looks"
id = Column(Integer, primary_key=True)
def __init__(self):
print "__init__ is run"
Base.__init__(self)
self.feedback = None
def set_feedback(self, feedback):
"""Status can either be 1 for liked, 0 no response, or -1 disliked.
"""
assert feedback in [1, 0, -1]
self.feedback = feedback
def get_feedback(self):
return self.feedback
And I am getting the following error:
Traceback (most recent call last):
File "/Volumes/Data2/Dropbox/projects/Giordano/venv/lib/python2.7/site-packages/flask/app.py", line 1701, in __call__
return self.wsgi_app(environ, start_response)
File "/Volumes/Data2/Dropbox/projects/Giordano/venv/lib/python2.7/site-packages/flask/app.py", line 1689, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/Volumes/Data2/Dropbox/projects/Giordano/venv/lib/python2.7/site-packages/flask/app.py", line 1687, in wsgi_app
response = self.full_dispatch_request()
File "/Volumes/Data2/Dropbox/projects/Giordano/venv/lib/python2.7/site-packages/flask/app.py", line 1360, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Volumes/Data2/Dropbox/projects/Giordano/venv/lib/python2.7/site-packages/flask/app.py", line 1358, in full_dispatch_request
rv = self.dispatch_request()
File "/Volumes/Data2/Dropbox/projects/Giordano/venv/lib/python2.7/site-packages/flask/app.py", line 1344, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Volumes/Data2/Dropbox/projects/Giordano/src/giordano/web/backend.py", line 94, in wrapped
ret = f(*args, **kwargs)
File "/Volumes/Data2/Dropbox/projects/Giordano/src/giordano/web/backend.py", line 81, in decorated
return f(*args, **kwargs)
File "/Volumes/Data2/Dropbox/projects/Giordano/src/giordano/web/backend.py", line 187, in next
json_ret = ge.encode(results) # automatically pulls the tags
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 201, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 264, in iterencode
return _iterencode(o, 0)
File "/Volumes/Data2/Dropbox/projects/Giordano/src/giordano/__init__.py", line 54, in default
jsonable = self.convert_to_jsonable(obj)
File "/Volumes/Data2/Dropbox/projects/Giordano/src/giordano/__init__.py", line 40, in convert_to_jsonable
image_url=obj.image_url, feedback=obj.get_feedback())
File "/Volumes/Data2/Dropbox/projects/Giordano/src/giordano/models.py", line 100, in get_feedback
return self.feedback
AttributeError: 'Look' object has no attribute 'feedback'
It seems to me that my __init__ method is not run as I can't see any print statements in my log.
Can someone explain why my __init__ is not run and what can I do for this?
Check out the SQLAlchemy documentation on reconstruction:
The SQLAlchemy ORM does not call __init__ when recreating objects from
database rows. The ORM’s process is somewhat akin to the Python
standard library’s pickle module, invoking the low level __new__
method and then quietly restoring attributes directly on the instance
rather than calling __init__.
If you need to do some setup on database-loaded instances before
they’re ready to use, you can use the #reconstructor decorator to tag
a method as the ORM counterpart to __init__. SQLAlchemy will call this
method with no arguments every time it loads or reconstructs one of
your instances. This is useful for recreating transient properties
that are normally assigned in your __init__:
from sqlalchemy import orm
class MyMappedClass(object):
def __init__(self, data):
self.data = data
# we need stuff on all instances, but not in the database.
self.stuff = []
#orm.reconstructor
def init_on_load(self):
self.stuff = []
When obj = MyMappedClass() is executed, Python calls the __init__
method as normal and the data argument is required. When instances are
loaded during a Query operation as in query(MyMappedClass).one(),
init_on_load is called.

Serializing output to JSON - ValueError: Circular reference detected

I'm trying to output results of my mysql query to JSON.
I have problem with serializing datetime.datetime field, so I wrote small function to do that:
def date_handler(obj):
if hasattr(obj, 'isoformat'):
return obj.isoformat()
else:
return obj
and then in main code I'm just running:
products_json = []
for code in best_matching_codes:
cur = db.cursor()
query = "SELECT * FROM %s WHERE code LIKE '%s'" % (PRODUCTS_TABLE_NAME, product_code)
cur.execute(query)
columns = [desc[0] for desc in cur.description]
rows = cur.fetchall()
for row in rows:
products_json.append(dict((k,v) for k,v in zip(columns,row)))
return json.dumps(products_json, default = date_handler)
However, since I wrote date_handler function, I'm getting "ValueError: Circular reference detected"
127.0.0.1 - - [10/Jan/2013 00:42:18] "GET /1/product?code=9571%2F702 HTTP/1.1" 500 -
Traceback (most recent call last):
File "/Library/Python/2.7/site-packages/flask/app.py", line 1701, in __call__
return self.wsgi_app(environ, start_response)
File "/Library/Python/2.7/site-packages/flask/app.py", line 1689, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/Library/Python/2.7/site-packages/flask/app.py", line 1687, in wsgi_app
response = self.full_dispatch_request()
File "/Library/Python/2.7/site-packages/flask/app.py", line 1360, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Library/Python/2.7/site-packages/flask/app.py", line 1358, in full_dispatch_request
rv = self.dispatch_request()
File "/Library/Python/2.7/site-packages/flask/app.py", line 1344, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/pisarzp/Desktop/SusyChoosy/susyAPI/test1.py", line 69, in product_search
return json.dumps(products_json, default = date_handler)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 238, in dumps
**kw).encode(obj)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 201, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 264, in iterencode
return _iterencode(o, 0)
ValueError: Circular reference detected
What did I break? Is there a better way to serialize output to JSON?
The function you pass as the default argument will only be called for objects that are not natively serializable by the json module. It must return a serializable object, or raise a TypeError.
Your version returns the same object you were passed if it's not of the one type you're fixing (dates). That is causing the circular reference error (which is misleading, since the circle is between one object and itself after being processed by date_handler).
You can start to fix this by changing date_handler to raise an exception in its else block. That will still probably fail, but you can probably then find out what object it is that is in your data structure causing the problem using code like this:
def date_handler(obj):
if hasattr(obj, 'isoformat'):
return obj.isoformat()
else:
raise TypeError(
"Unserializable object {} of type {}".format(obj, type(obj))
)
Instead of raising the TypeError yourself, you should relay the call to JSONEncoder's default-method:
def date_handler(obj):
if hasattr(obj, 'isoformat'):
return obj.isoformat()
else:
json.JSONEncoder.default(self,obj)
This will also raise TypeError and is a better practice, it allows for JSONEncoder to try and encode the type your method can't.
json.dumps(obj, default=method_name)
"method_name" function must be return a serialize object.
def method_name(obj):
data = {
'__class__': obj.__class__.__name__,
'__module__': obj.__module__
}
data.update(obj.__dict__)
return data

Categories

Resources