编辑 - 从下面获取代码并使其能够处理ForiegnKeys,十进制数字(尽管我正在进行非常强制的浮动转换)。它现在返回一个字典,因此可以递归。
from sqlobject import SQLObject
from decimal import Decimal
def sqlobject_to_dict(obj):
json_dict = {}
cls_name = type(obj)
for attr in vars(cls_name):
if isinstance(getattr(cls_name, attr), property):
attr_value = getattr(obj, attr)
attr_class = type(attr_value)
attr_parent = attr_class.__bases__[0]
if isinstance(getattr(obj, attr), Decimal):
json_dict[attr] = float(getattr(obj, attr))
elif attr_parent == SQLObject:
json_dict[attr] = sqlobject_to_dict(getattr(obj, attr))
else:
json_dict[attr] = getattr(obj, attr)
return json_dict
编辑 - 更改为添加实际数据模型 - 需要访问生成的值和需要处理的Decimal()列。
所以我看到了这个:return SQL table as JSON in python但它并不是我真正想要的东西 - 那是“蛮力” - 你需要知道对象属性的名称才能生成JSON响应。
我想做的是这样的事情(类的名称及其属性并不重要)
class BJCPStyle(SQLObject):
name = UnicodeCol(length=128, default=None)
beer_type = UnicodeCol(length=5, default=None)
category = ForeignKey('BJCPCategory')
subcategory = UnicodeCol(length=1, default=None)
aroma = UnicodeCol(default=None)
appearance = UnicodeCol(default=None)
flavor = UnicodeCol(default=None)
mouthfeel = UnicodeCol(default=None)
impression = UnicodeCol(default=None)
comments = UnicodeCol(default=None)
examples = UnicodeCol(default=None)
og_low = SGCol(default=None)
og_high = SGCol(default=None)
fg_low = SGCol(default=None)
fg_high = SGCol(default=None)
ibu_low = IBUCol(default=None)
ibu_high = IBUCol(default=None)
srm_low = SRMCol(default=None)
srm_high = SRMCol(default=None)
abv_low = DecimalCol(size=3, precision=1, default=None)
abv_high = DecimalCol(size=3, precision=1, default=None)
versions = Versioning()
def _get_combined_category_id(self):
return "%s%s" % (self.category.category_id, self.subcategory)
def _get_og_range(self):
low = self._SO_get_og_low()
high = self._SO_get_og_high()
if low == 0 and high == 0:
return "varies"
else:
return "%.3f - %.3f" % (low, high)
def _get_fg_range(self):
low = self._SO_get_fg_low()
high = self._SO_get_fg_high()
if low == 0 and high == 0:
return "varies"
else:
return "%.3f - %.3f" % (low, high)
def _get_srm_range(self):
low = self._SO_get_srm_low()
high = self._SO_get_srm_high()
if low == 0 and high == 0:
return "varies"
else:
return "%.1f - %.1f" % (low, high)
def _get_abv_range(self):
low = self._SO_get_abv_low()
high = self._SO_get_abv_high()
if low == 0 and high == 0:
return "varies"
else:
return "%.2f%% - %.2f%%" % (low, high)
def _get_ibu_range(self):
low = self._SO_get_ibu_low()
high = self._SO_get_ibu_high()
if low == 0 and high == 0:
return "varies"
else:
return "%i - %i" % (low, high)
是否有一种简单的方法,pythonic方式来编写那个神奇的to_json()函数?
答案 0 :(得分:3)
您可以将python json module与SQLObject sqlmeta类一起使用。像这样:
def to_json(obj):
return json.dumps(dict((c, getattr(obj, c)) for c in obj.sqlmeta.columns))
当我和你的班级Foo
一起运行时,我得到了:
>>> print to_json(f)
{"bar": "test", "lulz": "only for the", "baz": true}
编辑:如果你想在你的json字符串中包含magic attributes并且你不介意使用某种黑客攻击,你可能会滥用你的对象属性的事实python属性。例如,如果我将魔术属性foo
添加到原始样本类:
class Foo(SQLObject):
bar = UnicodeCol(length=128)
baz = BoolCol(default=True)
lulz = UnicodeCol(length=256)
def _get_foo(self):
return "foo"
然后我可以像这样定义to_json()
函数:
def to_json(obj):
cls = type(obj)
d = dict((c, getattr(obj, c)) for c in vars(cls) if isinstance(getattr(cls, c), property))
return json.dumps(d)
现在,如果我这样做:
f = Foo(bar = "test", lulz = "only for the")
print to_json(f)
我得到以下结果:
{"baz": true, "lulz": "only for the", "bar": "test", "foo": "foo"}
答案 1 :(得分:0)
import json
json.dumps(obj_instance.sqlmeta.asDict())
在我的情况下,这个对象包含json没有序列化的日期时间,所以我做了这样的事情:
json.dumps(dict((k, str(v)) for (k,v) in obj_instance.sqlmeta.asDict().items()))
答案 2 :(得分:0)
像这样......
class MyTable( sqlobject.SQLObject ):
# ... your columns ...
json.dumps({
'MyTable': [row.sqlmeta.asDict() for row in MyTable.select()]
}, indent=4, sort_keys=True )
假设您有一个名为sqlobject.SQLObject的派生类列表 '表'
Tables = [MyTable, ...]
def dump():
r={}
for t in Tables:
r[t.__name__] = [row.sqlmeta.asDict() for row in t.select()]
return json.dumps(r, indent=4, sort_keys=True)