1

编辑 - 从下面获取代码并使其可以处理 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() 函数?

4

3 回答 3

3

您可以将 python json 模块与 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 字符串中包含魔法属性并且你不介意使用一些技巧,你可能会滥用你的对象的属性是 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"}
于 2011-12-07T23:47:10.893 回答
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()))
于 2014-08-11T20:33:33.553 回答
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)
于 2017-03-11T02:14:54.800 回答