You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
For new projects you can start with a Python 3 with a fresh database.
26
+
For new projects, you can start with Python 3 with a fresh database.
27
27
To use an existing project in Python 3 though, you need to migrate your existing database first.
28
28
This section explains how to do that.
29
29
30
-
ZODB itself is compatible with Python 3 but a DB created in Python 2.7 cannot be used in Python 3 without modifying it before.
31
-
(See [Why do I have to migrate my database?] for technical background).
30
+
ZODB itself is compatible with Python 3, but a database created in Python 2.7 cannot be used in Python 3 without modifying it.
31
+
See {ref}`why-do-i-have-to-migrate-my-database-label` for technical background.
32
32
33
-
## Database Upgrade Procedure
34
33
35
-
In short you need to follow these steps to migrate your database:
34
+
## Database upgrade procedure
36
35
37
-
01. Upgrade your site to Plone 5.2 running on Python 2 first.
38
-
(see {doc}`upgrade-to-52`)
39
-
02. Make sure your code and all add-ons that you use work in Python 3.
40
-
(see {doc}`upgrade-to-python3`)
41
-
03. Backup your database!
42
-
04.**Pack** your database to **0 days** (`zodbupdate` will not update your database history and will leave old objects in place and you will not be able to pack your database in the future).
43
-
05. In your old buildout under Python 2, verify your database integrity using {py:mod}`zodbverify`.
36
+
Follow these steps to migrate your database.
37
+
38
+
1. Upgrade your site to Plone 5.2 running on Python 2 first.
39
+
See {doc}`upgrade-to-52`.
40
+
2. Make sure your code and all add-ons that you use work in Python 3.
41
+
See {doc}`upgrade-to-python3`.
42
+
3. Backup your database!
43
+
4._Pack_ your database to _0 days_.
44
+
`zodbupdate` will not update your database history, will leave old objects in place, and you will not be able to pack your database in the future.
45
+
5. In your old buildout under Python 2, verify your database integrity using {py:mod}`zodbverify`.
44
46
Solve integrity problems, if there are any.
45
-
06.Prepare your buildout for migrating the database to Python 3
46
-
07.Do **not** start the instance.
47
-
08.Migrate your database using {py:mod}`zodbupdate`
48
-
09.Verify your database integrity using {py:mod}`zodbverify`
47
+
6.Prepare your buildout for migrating the database to Python 3.
48
+
7.Do _not_ start the instance.
49
+
8.Migrate your database using {py:mod}`zodbupdate`.
50
+
9.Verify your database integrity using {py:mod}`zodbverify`.
49
51
If there are any problems, solve them and redo the migration.
50
52
10. Start the instance.
51
-
11. Manually check if all works as expected
53
+
11. Manually check if all works as expected.
54
+
55
+
56
+
(why-do-i-have-to-migrate-my-database-label)=
52
57
53
-
## Why Do I Have To Migrate My Database?
58
+
## Why do I have to migrate my database?
54
59
55
60
To understand the problem that arises when migrating a ZODB from Python 2 to Python 3,
56
61
this [introduction](https://blog.gocept.com/2018/06/07/migrate-a-zope-zodb-data-fs-to-python-3/) and the following example will help.
57
62
58
-
When pickling an object the datatypes and values are stored.
63
+
When pickling an object, the data types and values are stored.
59
64
60
-
In Python 2 strings get STRING, and Unicode gets UNICODE
65
+
In Python 2, strings get `STRING`, and Unicode gets `UNICODE`.
Python 3 does not allow non-ascii characters in bytes and the pickle declares the byte string as SHORT_BINBYTES and the string (py2 unicode) as BINUNICODE
97
+
Python 3 does not allow non-ASCII characters in bytes, the pickle declares the byte string as `SHORT_BINBYTES` and the string (Python 2 Unicode) as `BINUNICODE`.
93
98
94
99
```console
95
100
$ python3
@@ -123,8 +128,8 @@ SyntaxError: bytes can only contain ASCII literal characters.
123
128
highest protocol among opcodes = 3
124
129
```
125
130
126
-
Python 3 will wrongly interpret a pickle created with Python 2 that contains non-ascii characters in a field declared with OPTCODE `STRING`.
127
-
In that case we may end up with a `UnicodeDecodeError` for this pickle in `ZODB.serialize`
131
+
Python 3 will wrongly interpret a pickle created with Python 2 that contains non-ASCII characters in a field declared with `OPTCODE``STRING`.
132
+
In that case, we may end up with a `UnicodeDecodeError` for this pickle in `ZODB.serialize`.
## Verify The Integrity of the Database in Python 2
220
+
221
+
## Verify the integrity of the database in Python 2
214
222
215
223
The preflight verification of the database is run on Plone 5.2 in Python 2.
216
-
First check if all Python-pickles in the database can be loaded.
217
-
In older and grown projects it is possible to have pickles in there pointing to classes long gone in code.
224
+
First check if all Pythonpickles in the database can be loaded.
225
+
In older and mature projects, it is possible to have pickles in there pointing to classes long gone from the code.
218
226
Those may cause problems later.
219
227
220
228
Call `./bin/instance zodbverify` in your Python 2.7 setup.
221
-
If a problem pops up there is a debug mode with additional parameter `-D`, resulting in PDB with the pickle-data and a decompiled pickle in place to gather information about the source of the problem.
229
+
If a problem pops up, there is a debug mode with additional parameter `-D`, resulting in PDB with the pickle-data and a decompiled pickle in place to gather information about the source of the problem.
222
230
This enables solving the problem by either adding a stub class in the code or by deleting the object in the ZODB.
223
231
224
-
## Migrate Database using zodbupdate
232
+
233
+
## Migrate database using `zodbupdate`
225
234
226
235
The migration of the database is run on Plone 5.2 in Python 3.
227
-
It is expected to work equally in Python 3.6 and 3.7.
236
+
It is expected to work the same in Python 3.6, 3.7, or 3.8.
228
237
229
-
Run the migration by
238
+
Run the migration with appropriate arguments.
230
239
231
-
-passing the operation to undertake (`convert-py3`),
232
-
-the location of the database,
233
-
-the encoding expected and
234
-
-optional, encoding fallbacks if the database contains mixed encodings.
240
+
- The operation to perform, `convert-py3`.
241
+
- The location of the database.
242
+
- The encoding expected.
243
+
- Optionally, encoding fallbacks, if the database contains mixed encodings.
Ignoring index for /Users/pbauer/workspace/projectx/var/filestorage/Data.fs
248
256
Loaded 2 decode rules from AccessControl:decodes
@@ -253,54 +261,60 @@ Committing changes (#1).
253
261
```
254
262
255
263
```{note}
256
-
The blobstorage (holding binary data of files and images) will not be changed or even be read during the migration since the blobs only contain the raw binary data of the file/image.
264
+
The blob storage (holding binary data of files and images) will not be changed or even be read during the migration, because the blobs only contain the raw binary data of the file or image.
257
265
```
258
266
259
267
```{note}
260
-
The encoding should always be `utf8` and will be used when porting database-entries of classes where no encoding is specified in a `[zodbupdate.decode]` mapping in the package that holds the base-class.
268
+
The encoding should always be `utf8`, and will be used when porting databaseentries of classes where no encoding is specified in a `[zodbupdate.decode]` mapping in the package that holds the baseclass.
261
269
```
262
270
263
271
```{note}
264
272
The encoding fallback is optional and should not be provided by default.
265
-
If a `UnicodeDecodeError` occur, try to find out if the instance was configured with encodings different from `utf8`.
266
-
Provides those as encodings as fallback.
267
-
If in doubt try `latin1` since this was in former times of Zope the default encoding.
273
+
If a `UnicodeDecodeError` occurs, try to find out if the instance was configured with encodings different from `utf8`.
274
+
Provide those encodings as the `--encoding-fallback` argument.
275
+
If in doubt, try `latin1`, since this was in former times of Zope the default encoding.
268
276
```
269
277
270
-
## Test Migration
271
278
272
-
You can use the following command to check if all records in the database can be successfully loaded:
279
+
## Test migration
273
280
274
-
```console
281
+
You can use the following command to check if all records in the database can be successfully loaded.
282
+
283
+
```shell
275
284
bin/instance zodbverify
276
285
```
277
286
278
-
The output should look like this:
287
+
The output should look like the following.
279
288
280
289
```console
281
-
$ ./bin/instance zodbverify
282
-
283
290
INFO:Zope:Ready to handle requests
284
291
INFO:zodbverify:Scanning ZODB...
285
292
INFO:zodbverify:Done! Scanned 7781 records. Found 0 records that could not be loaded.
286
293
```
287
294
288
-
Most likely you will have additional log-messages, warnings and even errors.
295
+
Most likely you will have additional logmessages, warnings, and even errors.
289
296
290
297
```{note}
291
-
You can use the debug-mode with `./bin/instance zodbverify -D` which will drop you in a pdb each time a database-entry cannnot be unpickled so you can inspect it and figure out if that is a real issue or not.
298
+
You can use the debug mode with `./bin/instance zodbverify -D`.
299
+
This will drop you into a `pdb` session each time a database entry cannnot be unpickled
300
+
You can inspect it, and figure out if that is a real issue or not.
292
301
293
-
Before you start debugging you should read the following section on Troubleshooting because in many cases you can ignore the warnings.
302
+
Before you start debugging you should read the following section on {ref}`troubleshooting-zodbverify-label`, because in many cases you can ignore the warnings.
294
303
```
295
304
305
+
306
+
(troubleshooting-zodbverify-label)=
307
+
296
308
## Troubleshooting
297
309
298
-
### Data.fs.index broken
310
+
This section covers common issues when running `zodbverify`.
299
311
300
-
Delete `Data.fs.index` before migrating or you will get this error during migrating:
312
+
313
+
### `Data.fs.index` broken
314
+
315
+
Delete `Data.fs.index` before migrating, or you will get the following error during migrating.
ModuleNotFoundError: No module named 'PloneLanguageTool'
357
373
```
358
374
359
-
To work around this comment out the lines offending lines in `plone/app/upgrade/__init__.py` (do not forget to uncomment them after the migration!)
375
+
To work around this, comment out the lines offending lines in `plone/app/upgrade/__init__.py`.
376
+
Remember to uncomment them after the migration!
360
377
361
378
```python
362
379
# try:
@@ -371,17 +388,17 @@ To work around this comment out the lines offending lines in `plone/app/upgrade/
371
388
# ).PloneLanguageTool.LanguageTool.LanguageTool
372
389
```
373
390
374
-
### Migration Logs Errors And Warnings
391
+
### Migration logs errors and warnings
375
392
376
-
If there are log-messages during the migration or during `zodbverify` that does not necessarily mean that the migration did not work or that your database is broken.
377
-
For example if you migrated from Plone 4 to Plone 5 and then from Archetypes to Dexterity it is very likely that items in the database cannot be loaded because packages like `Products.Archetypes`, `plone.app.blob` or `plone.app.imaging` are not available.
378
-
These items are most likely remains that were not removed properly but are not used.
379
-
If your site otherwise works fine you can choose to ignore these issues.
393
+
If there are logmessages during the migration or during `zodbverify`, that does not necessarily mean the migration did not work, or that your database is broken.
394
+
For example, if you migrated from Plone 4 to Plone 5, and then from Archetypes to Dexterity, it is very likely that items in the database cannot be loaded, because packages such as `Products.Archetypes`, `plone.app.blob`, or `plone.app.imaging` are not available.
395
+
These items most likely remain, and were not removed properly and are not used.
396
+
If your site otherwise works fine, you can choose to ignore these issues.
380
397
381
-
Here is the output of a migration start started in Plone 4 with Archetypes.
398
+
Here is the output of a migration started in Plone 4 with Archetypes.
382
399
The site still works nicely in Plone 5.2 on Python 3.7 despite the warnings and errors:
383
400
384
-
```
401
+
```console
385
402
Updating magic marker for var/filestorage/Data.fs
386
403
Loaded 2 decode rules from AccessControl:decodes
387
404
Loaded 12 decode rules from OFS:decodes
@@ -459,16 +476,17 @@ Found new rules: {
459
476
}
460
477
```
461
478
462
-
## Downtime
463
479
464
-
Some thoughts on doing upgrades without downtime that came up in a Hangout during a coding sprint in October 2018:
480
+
## Eliminating downtime
481
+
482
+
You can try the following to have an upgrade without downtime.
465
483
466
-
- You can try to leverage the ZRS replication protocol, where the secondary server has the converted data.
467
-
It would probably be a trivial change to ZRS to get this to work.
468
-
-For Relstorage there is a ZRS equivalent for Relstorage: <http://www.newtdb.org/en/latest/topics/following.html>
484
+
-You can try to leverage the ZRS replication protocol, where the secondary server has the converted data.
485
+
It would probably be a trivial change to ZRS to get this to work.
486
+
- There is a [ZRS equivalent for Relstorage](https://www.newtdb.org/en/latest/topics/following.html).
469
487
470
-
## Further Reading
471
488
472
-
The Zope Documentation contains a [section about ZODB migration](https://zope.readthedocs.io/en/latest/zope4/migration/zodb.html)
0 commit comments