Migrations in mongoengine: InvalidId

2024/10/5 15:30:33

I am working with mongoengine and trying to do a simple migration. I have a field which I would like to migrate from being a StringField to a ReferenceField to another Object. I planned on doing the migration by hand, first constructing the new object based on the string that comes from the old StringField and then setting it explicitly.

The problem is I cannot even access one of the top level documents anymore once I changed the field type. Is it required to create a "dummy" field in the my document's class code as a placeholder for the new field? This seems kludgy to me so I assume there is a better way?

Here is the error, which is because the field coming out of the DB (StringField) is not consistent with a reference field.

/usr/lib/python2.7/site-packages/mongoengine/queryset/base.pyc in __getitem__(self, key)149                 return queryset._get_as_pymongo(queryset._cursor.next())150             return queryset._document._from_son(queryset._cursor[key],
--> 151                                                 _auto_dereference=self._auto_dereference)152         raise AttributeError153 /usr/lib/python2.7/site-packages/mongoengine/base/document.pyc in _from_son(cls, son, _auto_dereference)568                 try:569                     data[field_name] = (value if value is None
--> 570                                         else field.to_python(value))571                     if field_name != field.db_field:572                         del data[field.db_field]/usr/lib/python2.7/site-packages/mongoengine/fields.pyc in to_python(self, value)935            not isinstance(value, (DBRef, Document, EmbeddedDocument))):936             collection = self.document_type._get_collection_name()
--> 937             value = DBRef(collection, self.document_type.id.to_python(value))938         return value939 /usr/lib/python2.7/site-packages/mongoengine/base/fields.pyc in to_python(self, value)390     def to_python(self, value):391         if not isinstance(value, ObjectId):
--> 392             value = ObjectId(value)393         return value394 /usr/lib/python2.7/site-packages/bson/objectid.pyc in __init__(self, oid)88             self.__generate()89         else:
---> 90             self.__validate(oid)91 92     @classmethod/usr/lib/python2.7/site-packages/bson/objectid.pyc in __validate(self, oid)192                     raise InvalidId("%s is not a valid ObjectId" % oid)193             else:
--> 194                 raise InvalidId("%s is not a valid ObjectId" % oid)195         else:196             raise TypeError("id must be an instance of (%s, %s, ObjectId), "InvalidId: Was Dirty: a2111fe89383bb562738b81c2b63fe78e877ed32 is not a valid ObjectId
Answer

I've always migrated things by hand using an intermediate collection or an intermediate field in the same collection, but this example makes it look like you don't have to. Stack overflow hates external links so I'm including the example verbatim below. BTW be careful with that "drop_collection" part!

import unittest
from mongoengine import *class Test(unittest.TestCase):def setUp(self):conn = connect(db='mongoenginetest')def create_old_data(self):class Person(Document):name = StringField()age = FloatField()  # Save as stringmeta = {'allow_inheritance': True}Person.drop_collection()Person(name="Rozza", age=35.00).save()rozza = Person._get_collection().find_one()self.assertEqual(35.00, rozza['age'])def test_migration(self):self.create_old_data()class Person(Document):name = StringField()age = StringField()meta = {'allow_inheritance': True}for p in Person.objects:p.age = "%s" % p.agep.save()rozza = Person.objects.first()self.assertEqual("35.0", rozza.age)if __name__ == '__main__':unittest.main()
https://en.xdnf.cn/q/70471.html

Related Q&A

Keras pretrain CNN with TimeDistributed

Here is my problem, I want to use one of the pretrain CNN network in a TimeDistributed layer. But I have some problem to implement it.Here is my model:def bnn_model(max_len):# sequence length and resne…

How to `pause`, and `resume` download work?

Usually, downloading a file from the server is something like this: fp = open(file, wb) req = urllib2.urlopen(url) for line in req:fp.write(line) fp.close()During downloading, the download process just…

AttributeError: module rest_framework.serializers has no attribute NullBooleanField

After upgrading djangorestframework from djangorestframework==3.13.1 to djangorestframework==3.14.0 the code from rest_framework.serializers import NullBooleanFieldThrowsAttributeError: module rest_fra…

Pandas convert dataframe values to column names

I want to use dataframe values as column names and simplify the dataframe.I tried df.stack() and then index.map({0[0]}_{0[1]}.format)Input_df(Got this df by doing a groupby):link price dateA 1 …

Pandas replace part of string with values from dictionary

I would like to replace the words in my dataframedf = pd.DataFrame({"Text": ["The quick brown fox jumps over the lazy dog"]})which match the keys in the following dictionarydic = {&…

Tensorflow autoencoder cost not decreasing?

I am working on unsupervised feature learning using autoencoders using Tensorflow. I have written following code for the Amazon csv dataset and when I am running it the cost is not decreasing at every …

Seconds since epoch to relative date

Im working with dates since epoch, and already got, for example:date = 6928727.56235Id like to transform this into another relative format, so that Ill be able to transform this into something relative…

ring buffer with numpy/ctypes

Im developing a client which will receive the [EEG] data over tcp and write it to the ring buffer. I thought it can be very convenient to have the buffer as a ctypes or numpy array because its possible…

Get all available timezones

Im currently working on an application that is required to support multiple timezones.For that, Im using the dateutil library. Now, I need a way to present the user a list of all available timezones th…

Load blob image data into QPixmap

I am writing a program using PyQt4 for front-end GUI and this program accesses a back-end database (which can be either MySQL or SQLite). I need to store some image data in the database and below is th…