<div dir="ltr">Caveat to this below.<br><div><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Jul 15, 2013 at 7:54 AM, Marius Gedminas <span dir="ltr"><<a href="mailto:marius@gedmin.as" target="_blank">marius@gedmin.as</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="im">On Mon, Jul 15, 2013 at 03:36:21PM +0200, Pedro Ferreira wrote:<br>
> We need to move a considerable number of persistent objects (~40K) from<br>
> one module to another, and we were wondering what is the best strategy<br>
> to follow.<br>
</div>...<br>
<div class="im">> Has anyone ever done anything like this? Which approach have you<br>
> followed? Any suggestions?<br>
<br>
</div>1. Make sure all the classes are still importable from the old location<br>
   ('from newmodule import MyPersistentSomething # BBB')<br>
<br>
That is sufficient to make it work.  If you also want to eradicate all<br>
references to the old module name from your ZODB (e.g. because you'd<br>
like to remove the BBB import), then proceed to step 2:<br>
<br>
2. Write a script that loads every instance of this class and does a<br>
<br>
   obj._p_activate()  # actually not sure this is required, but won't hurt<br>
   obj._p_changed = True<br>
<br>
and then commit the transaction.  Do the commit multiple times, after<br>
each batch of several hundred objects, to avoid excessive memory usage.<br>
Also be sure to handle conflict errors and retry that batch if you're<br>
running this script on the live system.  Finding all instances is left<br>
as an exercise for the reader (sometimes findObjectsProviding() helps,<br>
if you use nested containers everywhere; sometimes application-specific<br>
logic works best; sometimes you end up having to use ZODB iterators to<br>
loop through every single object in the DB -- I believe zodbupdate does<br>
that.)<br></blockquote><div><br></div><div>This works only partially, AFAICT.  It will update the stored class name of a persistent object.  It will not seek out and change the class name of the object in a reference.  Your step 3 (removing the BBB code) can break things (broken objects) as a result of this.  Fixing persistent objects is half the battle if you get broken references to them.  <br>
<br>You can verify that this is incomplete by creating a PersistentMapping of some simple objects, perform the trick above, commit, then pack.  You will still have the old BBB classname stored in the database in the references, unless you do a _p_changed=1 on the mapping containing/referencing the items as well (then commit).</div>
<div><br></div><div>I am not sure how to walk/iterate all oids for all transactions to get all possible referencing objects (I assume this is storage-specific, maybe building a reference map like Lawrence Rowe has done [1]).  This might be necessary to update the referencing objects?<br>
</div><div><br>[1] <a href="http://plone.org/documentation/kb/debug-zodb-bloat/inspectZodbUtils.py">http://plone.org/documentation/kb/debug-zodb-bloat/inspectZodbUtils.py</a><br><br></div><div>Sean</div></div><br><br></div>
</div></div>