milesrichardson / ParsePy

A relatively up-to-date fork of ParsePy, the Python wrapper for the Parse.com API. Originally maintained by @dgrtwo
MIT License
515 stars 184 forks source link

Nodechef.com returns only last object with valid data #160

Closed josefkaeufl closed 7 years ago

josefkaeufl commented 7 years ago

Hi,

I currently have the problem that my app is requesting data from my nodechef.com Parse database, but only the last with python created item returns a valid object. Here is my python code:

class Url(Object):
    pass

file = open("Input.txt")
arrayList = []
lastobjectindex = 0

for line in file :
    anyObject = Url()
    anyObject.url = line
    lastobjectindex = lastobjectindex + 1
    anyObject.idx = lastobjectindex
    arrayList.append(deepcopy(anyObject))
file.close()

batcher = ParseBatcher()
batcher.batch_save(arrayList)

When I request the object with idx 1 in swift , I get back an object (without error) but without any data. This happens for all objects in the database except the last one. Any other manually created object using the parse dashboard works fine in my swift app.

Any ideas, what I am doing wrong? Creating each object one after another in the for loop has the same effect.

milesrichardson commented 7 years ago

Just guessing, but the problem is probably with deepcopy. It could also be with your method of reading lines. Try rewriting the loop like this:

class Url(Object):
    pass

arrayList = []

with open("Input.txt", "r") as fh:
    for idx, line in enumerate(fh.readlines()):
        arrayList.append(Url(idx=idx, url=line.strip()))

batcher = ParseBatcher()
batcher.batch_save(arrayList)
josefkaeufl commented 7 years ago

Works perfectly. Thanks!!! But I don't understand why mine isn't... :)

milesrichardson commented 7 years ago

I take it you're new to Python, and coming from Swift it can look similar in syntax, but there are some crucial differences. I encourage you to read up on the fundamentals of Python and the idiosyncrasies of the language (e.g. Python is primarily pass by reference while Swift is pass by value unless explicitly instructed otherwise).

Your mistake here is abusing deepcopy. Try to avoid it as much as you can, because it's behavior on custom objects can be unpredictable. In the case of ParsePy, the code uses metaclass features which almost certainly cause problems with deepcopy. deepcopy is a serializing function for translating the "value" of the object according to a predefined set of rules, into another object. It's not much different than serializing to JSON. That means that for complex objects with strange behaviors, like those with inheriting from a metaclass, you need to write a custom function to override its default behavior. ParsePy does not have a deepcopy function implemented on its objects, so this is causing problems.

What was happening:

Some other things:

milesrichardson commented 7 years ago

I highly suggest this guide: http://docs.python-guide.org/en/latest/