Как сделать объект Python JSON-сериализованным? - PullRequest
0 голосов
/ 01 марта 2019

Я хочу serialize a python object, после сохранения его в mysql (на основе Django ORM) я хочу получить его и передать этот объект функции, которой нужен такой объект в качестве параметра.

Следующие две части являются моим основным логическим кодом:

1 часть сохранения параметров:



class Param(object):
    def __init__(self, name=None, targeting=None, start_time=None, end_time=None):
        self.name = name
        self.targeting = targeting
        self.start_time = start_time
        self.end_time = end_time
    #...

param = Param()
param.name = "name1"
param.targeting= "targeting1"


task_param = {
            "task_id":task_id,              # string
            "user_name":user_name,          # string
            "param":param,                  # Param object
            "save_param":save_param_dict,   # dictionary
            "access_token":access_token,    # string
            "account_id": account_id,       # string
            "page_id": page_id,             # string
            "task_name":"sync_create_ad"    # string
        }


class SyncTaskList(models.Model):
    task_id = models.CharField(max_length=128, blank=True, null=True)
    ad_name = models.CharField(max_length=128, blank=True, null=True)
    user_name = models.CharField(max_length=128, blank=True, null=True)
    task_status = models.SmallIntegerField(blank=True, null=True)
    task_fail_reason = models.CharField(max_length=255, blank=True, null=True)
    task_name = models.CharField(max_length=128, blank=True, null=True)
    start_time = models.DateTimeField()
    end_time = models.DateTimeField(blank=True, null=True)
    task_param = models.TextField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'sync_task_list'



SyncTaskList(
                task_id=task_id,
                ad_name=param.name,
                user_name=user_name,
                task_status=0,
                task_param = task_param,
            ).save()

2 часть использования параметров


def add_param(param, access_token):
    pass

task_list = SyncTaskList.objects.filter(task_status=0)
for task in task_list:
    task_param = json.loads(task.task_param)
    add_param(task_param["param"], task_param["access_token"]) # pass param object to function add_param

Если я напрямую использую Django ORM для сохранения task_param в mysql, я получаю ошибку,

json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

, после операции ORM я получаю строку, имя свойства которой заключено в одинарные кавычки, например:


# in mysql it saved as 

 task_param: " task_param: {'task_id': 'e4b8b240cefaf58fa9fa5a591221c90a',
              'user_name': 'jimmy',
              'param': Param(name='name1',
                                    targeting='geo_locations',
                                   ),
              'save_param': {}}"


Теперь я путаюсь с сериализацией объекта python, тогда как загрузить этот оригинальный объект и передать его функции?

Любой комментарий оченьДобро пожаловать.большое спасибо.

пока что обновите мое решение

task_param = {
            # ...
            "param":vars(param),            # turn Param object to dictionary 
            # ...
            }

SyncTaskList(
                #...
                task_param = json.dumps(task_param),
                #...
            ).save()

#task_list = SyncTaskList.objects.filter(task_status=0)
#for task in task_list:
    task_param = json.loads(task.task_param)
    add_param(Param(**task_param["param"]), task_param["access_token"])

обновление на основе ответа @ AJS

напрямую pickle dumps и сохранил его как binary field, затем pickle loads он также работает


Есть ли лучшее решение для этого?

Ответы [ 2 ]

0 голосов
/ 01 марта 2019

Попробуйте заглянуть в msgpack https://msgpack.org/index.html

в отличие от pickle, который специфичен для python, msgpack поддерживается многими языками (поэтому язык, используемый для записи в mysql , может отличатьсячем язык, используемый для чтения).

Есть также несколько проектов, которые интегрируют эти библиотеки сериализатора в поля модели Django:

0 голосов
/ 01 марта 2019

Вы можете использовать pickle, в основном вы сериализуете свой объект python и сохраняете его как байты в своей базе данных MySQL, используя BinaryField в качестве типа поля модели в Django, поскольку я не думаю, что JSONСериализация будет работать в вашем случае, так как у вас есть объект Python в качестве значения, а также в вашем dict, когда вы извлекаете ваши данные из db, просто распаковываете его синтаксис похож на библиотеку json, см. ниже.

import pickle
#to pickle
data = pickle.dumps({'name':'testname'})
# to unpickle just do
pickle.loads(data)

, поэтомув вашем случае, когда вы откручиваете свой объект, вы должны получить данные в том же виде, в каком они были до засолки.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...