I have written a Python program to take the backup of all objects of MySQL db individually. The program works fine when run on my machine, but when I use cx_freeze to create an executable file, it fails to run on the other machine. I found the cause of the error to be the text file for configuration. When I don't write a configuration file, the program runs fine, else it gives an error.
My code for extraction: mysql_extractor.py. Please have a look at the filter_parsing function, the probable source of error.
[mysql_extractor.py]
#!/usr/bin/env python3
"""
__title__ = "mysql_extractor.py"
__description__ = "Script to extract objects of MySQL database individually"
"""
from __future__ import print_function
import argparse
import os
import sys
import pymysql
import encodings.idna
class MySQLExtractor:
############################################
#
# PUBLIC METHODS
#
############################################
directory = ""
dumpcmd = ""
def parse_argument(self):
self.parser = argparse.ArgumentParser(description="MySQL dump process")
args_conn = self.parser.add_argument_group(title="Database Connection")
args_conn.add_argument('--host', dest="hostname", default="127.0.0.1", help="Host name or IP Address")
args_conn.add_argument('-u', '--username', dest="username", default="root", help="Database user name.")
args_conn.add_argument('--password', dest="password", default="", help="Password for the given user.")
args_conn.add_argument('-d', '--db', dest="db", default="test", help="Database name to connect to.")
args_filter = self.parser.add_argument_group(title="Filters", description="All object names given in any filter MUST be fully schema qualified.")
args_filter.add_argument('--gettables', dest="gettables", action="store_true", help="Get all tables only")
self.args = self.parser.parse_args()
# end _parse_arguments()
def gettables(self):
try:
print ("Dumping Tables..")
conn = pymysql.connect(host=self.args.hostname, user=self.args.username, passwd=self.args.password, database=self.args.db)
cursor = conn.cursor()
if not os.path.exists("tables"):
os.makedirs("tables")
os.chdir("tables")
query = "show full tables where Table_Type != 'VIEW'"
cursor.execute(query)
for row in cursor:
dumpcmd = self.dumpcmd
dumpcmd += " " + row[0] + " --no-data > " + row[0] + ".sql"
os.system(dumpcmd)
os.chdir(self.directory)
cursor.close()
conn.close()
except pymysql.Error as e:
print("Error lin connecting to the DB: " + str(e) )
sys.exit(2)
# end gettables
def filter_parsing(self):
"""
Some more code here, but not relevant to the question
"""
self.directory = self.args.db
os.makedirs(self.directory)
os.chdir(self.directory)
# Create config file <Probable source of error>
filename = "my_config"
f = open(filename, 'w')
f.write("[mysqldump]\n")
f.write("host='"+ self.args.hostname + "'\n")
f.write("user='"+ self.args.username + "'\n")
f.write("password='"+ self.args.password + "'\n")
f.close()
self.directory = os.getcwd()
self.dumpcmd = "mysqldump --defaults-file=" + self.directory + "/my_config" +" --skip-dump-date " + self.args.db
# If the following command is used and config file is not created, it gives no error.
# self.dumpcmd = "mysqldump -u " + self.args.username + " -h " + self.args.hostname + " --password=" + self.args.password + " --skip-dump-date " + self.args.db
#gettables is selected
if self.args.gettables==True:
self.gettables()
return
# end filter_parsing
#end class MySQLExtractor
p = MySQLExtractor()
p.parse_argument()
try:
p.filter_parsing()
finally:
print ("Done")
This code works fine when run on my machine. But when I create an executable file and run it on other machine, it gives error(s). Here is my setup.py file
[setup.py]
import sys
from cx_Freeze import setup, Executable
# Dependencies are automatically detected, but it might need fine tuning.
build_exe_options = {"packages": ["os","MySQLdb"], "excludes": ["tkinter"]}
# GUI applications require a different base on Windows (the default is for a
# console application).
base = None
if sys.platform == "win32":
base = "Win32GUI"
setup( name = "extractor",
version = "0.1",
description = "My GUI application!",
options = {"build_exe": build_exe_options},
executables = [Executable("mysql_extractor.py", base=base)])
The error thrown is:
Traceback (most recent call last):
File "<frozen importlib._bootstrap>", line 2237, in _find_and_load
File "<frozen importlib._bootstrap>", line 2226, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 1191, in _load_unlocked
File "<frozen importlib._bootstrap>", line 1161, in _load_backward_compatible
File "/usr/lib64/python3.4/site-packages/cx_Freeze-5.0-py3.4-linux-x86_64.egg/cx_Freeze/initscripts/__startup__.py", line 12, in <module>
File "<frozen importlib._bootstrap>", line 2237, in _find_and_load
File "<frozen importlib._bootstrap>", line 2226, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 1191, in _load_unlocked
File "<frozen importlib._bootstrap>", line 1161, in _load_backward_compatible
File "/usr/lib64/python3.4/site-packages/cx_Freeze-5.0-py3.4-linux-x86_64.egg/cx_Freeze/initscripts/Console.py", line 21, in <module>
File "<frozen importlib._bootstrap>", line 2237, in _find_and_load
File "<frozen importlib._bootstrap>", line 2226, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 1191, in _load_unlocked
File "<frozen importlib._bootstrap>", line 1161, in _load_backward_compatible
File "/home/AD/abhishek.bhola/Documents/tmp/tmp_test.py", line 97, in <module>
File "/home/AD/abhishek.bhola/Documents/tmp/tmp_test.py", line 74, in filter_parsing
File "<frozen importlib._bootstrap>", line 2237, in _find_and_load
File "<frozen importlib._bootstrap>", line 2222, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 2164, in _find_spec
File "<frozen importlib._bootstrap>", line 1940, in find_spec
File "<frozen importlib._bootstrap>", line 1916, in _get_spec
File "<frozen importlib._bootstrap>", line 1897, in _legacy_get_spec
File "<frozen importlib._bootstrap>", line 863, in spec_from_loader
File "<frozen importlib._bootstrap>", line 904, in spec_from_file_location
OSError: zipimport: can not open file ./lib64/python34.zip
This problem has been detected and is already solved in the source repository. The problem is the os.chdir() call that is made when using relative paths to start up the executable. You have three choices for now: