Restoring an Odoo Database with Python3 and xmlrpc failing

519 views Asked by At

I am writing a python script to backup and restore an Odoo database (copy, really).

My code to make the backup is as follows:

def download_db() :
    conn = ServerProxy(url + '/xmlrpc/db')
    print ('Dumping database...')

    with open(backup_zip_name, 'wb') as backup_file:
        decode = base64.b64decode(conn.dump(master_password, db_to_copy, 'zip'))
        backup_file.write(decode)

This seems to work fine and I can successfully restore the generated backup file manually using the odoo web database manager interface.

However when I try to restore that backup via the script:

def restore_db() :
    with open(backup_zip_name, 'rb') as backup_file:
        serv = ServerProxy(url + '/xmlrpc/db')
        print('Creating database ' + new_db_name + ' from ' + backup_zip_name)
        
        serv.restore(master_password, new_db_name, base64.b64encode(backup_file.read()))
        print('done')

I get the following error:

Creating database db_copy from ./backup/backup.zip Traceback (most recent call last): File "/usr/bin/anonymisation/odoo-database-copy.py", line 97, in restore_db() File "/usr/bin/anonymisation/odoo-database-copy.py", line 40, in restore_db serv.restore(master_password, new_db_name, encode) File "/opt/rh/rh-python36/root/usr/lib64/python3.6/xmlrpc/client.py", line 1112, in call return self.__send(self.__name, args) File "/opt/rh/rh-python36/root/usr/lib64/python3.6/xmlrpc/client.py", line 1452, in __request verbose=self.__verbose File "/opt/rh/rh-python36/root/usr/lib64/python3.6/xmlrpc/client.py", line 1154, in request return self.single_request(host, handler, request_body, verbose) File "/opt/rh/rh-python36/root/usr/lib64/python3.6/xmlrpc/client.py", line 1170, in single_request return self.parse_response(resp) File "/opt/rh/rh-python36/root/usr/lib64/python3.6/xmlrpc/client.py", line 1342, in parse_response return u.close() File "/opt/rh/rh-python36/root/usr/lib64/python3.6/xmlrpc/client.py", line 656, in close raise Fault(**self._stack[0]) xmlrpc.client.Fault: <Fault object of type 'Binary' has no len(): 'Traceback (most recent call last):\n File "/opt/rh/rh-python36/root/usr/lib/python3.6/site-packages/odoo-12.0.post20181107-py3.6.egg/odoo/addons/base/controllers/rpc.py", line 54, in xmlrpc_1\n response = self._xmlrpc(service)\n File "/opt/rh/rh-python36/root/usr/lib/python3.6/site-packages/odoo-12.0.post20181107-py3.6.egg/odoo/addons/base/controllers/rpc.py", line 43, in _xmlrpc\n result = dispatch_rpc(service, method, params)\n File "/opt/rh/rh-python36/root/usr/lib/python3.6/site-packages/odoo-12.0.post20181107-py3.6.egg/odoo/http.py", line 120, in dispatch_rpc\n result = dispatch(method, params)\n File "/opt/rh/rh-python36/root/usr/lib/python3.6/site-packages/odoo-12.0.post20181107-py3.6.egg/odoo/service/db.py", line 448, in dispatch\n return gexp_method_name\n File "", line 2, in exp_restore\n File "/opt/rh/rh-python36/root/usr/lib/python3.6/site-packages/odoo-12.0.post20181107-py3.6.egg/odoo/service/db.py", line 40, in if_db_mgt_enabled\n return method(self, *args, **kwargs)\n File "/opt/rh/rh-python36/root/usr/lib/python3.6/site-packages/odoo-12.0.post20181107-py3.6.egg/odoo/service/db.py", line 248, in exp_restore\n for chunk in chunks(data):\n File "/opt/rh/rh-python36/root/usr/lib/python3.6/site-packages/odoo-12.0.post20181107-py3.6.egg/odoo/service/db.py", line 244, in chunks\n for i in range(0, len(d), n):\nTypeError: object of type 'Binary' has no len()\n'>

I am running the script using python 3.6. Any ideas how to fix this please?

ETA: They both work fine on python 2.7

1

There are 1 answers

0
Kenly On BEST ANSWER

base64.b64encode return a string in python2.7 and bytes in Python3.6.

Try to pass a string instead of bytes to the restore function:

base64.b64encode(backup_file.read()).decode()