2

I've got a little problem:

I have a String in my Database which is called actions. Now, I'm writing a method, which gets that string from the database (that works), and then I want to turn that string into a list.

I know actions.split(), but this didn't work out so well for me, because if my string looks like this:

actions = [
    {u'action': 'visit_testing', u'timestamp': datetime.datetime(2016, 2, 12, 13, 32, 14)},
    {u'action': 'visit_foo', u'timestamp': datetime.datetime(2016, 2, 12, 13, 37, 50)}
]

I can't use actions.split(', ') because it would mess up the dictionaries inside.

Till now I've got the following code:

timestamp = datetime.now().replace(microsecond=0)
dict = {'timestamp': timestamp, 'action': action}

if self.actions:
    actions_string = str(self.actions)
    actions_stripped = actions_string.strip('[')
    actions_stripped = actions_stripped.strip(']')
    actions_splitted = actions_stripped.split(', ')

    new_action_list = []

    buffer = ''
     for string in actions_splitted:
        if '{' in string:
            buffer = str(string)
        elif '}' in string:
            buffer = buffer + ', ' + str(string)
            new_action_list.append(str(buffer))
            buffer = ''
        else:
            buffer = buffer + ', ' + str(string)
    self.actions = str(buffer)
    self.last_action = datetime.now().replace(microsecond=0)
    self.save()
else:
    self.actions = '['+str(dict)+']'
    self.last_action = datetime.now().replace(microsecond=0)
    self.save()

Addition: If I run the method when actions is empty, it gives me a list with one dictionary, but if I run it when it already has something in it, if sets actions to "".

1
  • 3
    "I have a String in my Database", you have json forced in as a string in your database, it probably needs to be a JSONFieldor an actual object model Commented Feb 12, 2016 at 12:47

3 Answers 3

2

You should be using the json module to store valid JSON in your database. You can create a valid action list from that string using exec. But please beware that using exec or eval is a potentially dangerous practice.

import datetime

stuff = '''
actions = [{u'action': 'visit_testing', u'timestamp': datetime.datetime(2016, 2, 12, 13, 32, 14)}, {u'action': 'visit_foo', u'timestamp': datetime.datetime(2016, 2, 12, 13, 37, 50)}]
'''

exec(stuff)
print(actions)
print(actions[0]['timestamp'])    

output

[{u'action': 'visit_testing', u'timestamp': datetime.datetime(2016, 2, 12, 13, 32, 14)}, {u'action': 'visit_foo', u'timestamp': datetime.datetime(2016, 2, 12, 13, 37, 50)}]
2016-02-12 13:32:14
Sign up to request clarification or add additional context in comments.

Comments

1

Use json library.

import json
my_dict_or_list = json.loads(your_string)

then work with Python objects. You will gain so much time :-D

9 Comments

now i'm getting Expecting property name enclosed in double quotes: line 1 column 3 (char 2)
json keys in dict are enclosed with double quotes, not simple quote. Can you have your string with these quotes ?
I tried to change this line dict = {"timestamp": timestamp, "action": action}, but the quotes were changed back into single quotes... can i do .replace("'", '"')?
It should works but beware of string with escaped quote is your dict (i don't know if you can have some)
Why use json.loads() on something that's not json?
|
-2

I found a way that works for me:

    timestamp = datetime.datetime.now().replace(microsecond=0)

    if self.actions:
        new_dict = {"timestamp": timestamp, "action": action}
        #tmp_actions = json.loads(self.actions)
        tmp_actions = self.actions
        exec(tmp_actions)
        actions.append(new_dict)
        self.actions = str('actions = '+str(actions))
        self.last_action = datetime.datetime.now().replace(microsecond=0)
        self.save()
    else:
        exec('''actions = ['''+str({"timestamp": timestamp, "action": action})+''']''')
        self.actions = 'actions = '+str(actions)
        self.last_action = datetime.datetime.now().replace(microsecond=0)
        self.save()

Thanks for all the help.

4 Comments

This code will get you into trouble one day or another. Image what will happens if someone stores something like "os.system("rm -rf")" in your database...
@brunodesthuilliers Yea, i know, but I guess I could write a method which checks if the text is "valid" (looks if a specific format is there)
As far as I'm concerned, I wouldn't bet my system security on this. Seriously, you'd better switch to (at least) json and write a run-once migration script for your current dat. Or use a properly normalized relational schema storing "actions" in their own table, one row per action.
Well, I guess I'm going to create its own table then

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.