从SQLObject创建JSON对象的更简单方法
编辑——从下面获取代码,使其能够处理ForiegnKeys、十进制数(尽管我正在进行非常强制的浮点转换)。它现在返回一个dict,因此可以递归从SQLObject创建JSON对象的更简单方法,json,python,sqlobject,Json,Python,Sqlobject,编辑——从下面获取代码,使其能够处理ForiegnKeys、十进制数(尽管我正在进行非常强制的浮点转换)。它现在返回一个dict,因此可以递归 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 is
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
EDIT--更改为添加实际的数据模型--有需要访问的生成值和需要处理的Decimal()列
我看到了:但这并不是我真正想要的——这是“暴力”——为了生成JSON响应,您需要知道对象属性的名称
我想做的事情是这样的(类的名称和属性并不重要)
有没有一种简单的、类似python的方法来编写这个神奇的函数?您可以将python与SQLObject类一起使用。像这样:
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}
Edit:如果您想在json字符串中包含内容,并且不介意使用一些技巧,那么您可以滥用对象的属性是python属性这一事实。例如,如果我向原始示例类添加了一个magic属性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)
json.dumps(dict((k, str(v)) for (k,v) in obj_instance.sqlmeta.asDict().items()))
现在,如果我这样做:
f = Foo(bar = "test", lulz = "only for the")
print to_json(f)
我得到以下结果:
{"baz": true, "lulz": "only for the", "bar": "test", "foo": "foo"}
在我的例子中,这个对象包含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)
json.dumps(dict((k, str(v)) for (k,v) in obj_instance.sqlmeta.asDict().items()))
像这样的
class MyTable( sqlobject.SQLObject ):
# ... your columns ...
json.dumps({
'MyTable': [row.sqlmeta.asDict() for row in MyTable.select()]
}, indent=4, sort_keys=True )
假设您有一个名为
“桌子”
这是可行的,但我应该发布我的整个数据模型——它的作用远不止sqlmeta.columns的帮助。请注意get*\u range()方法。JSON结果中实际上不需要十进制列,因此这些列很容易用if语句过滤掉。我已经用包含magic attributes.accepted和upvote的hack编辑了我的答案!废话,我从来没有把类型放在一起——这是我过滤掉十进制字段的方式(它实际上生成了派生数据)。如果可以,我会给你更多的机会!
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)