0%

python打包程序移植到生产环境redhat出现的问题

1.出现问题及解决

1.1 python打包访问oracle数据库无instantclient相关问题

1.1.1 问题1:cx_Oracle.DatabaseError: DPI-1047: 64-bit Oracle Client library cannot be loaded解决方法”

解决方法:本机安装instantclient,安装步骤如下(参考:http://www.360doc.com/content/12/1103/21/8827884_245559524.shtml)

1
rpm -ivh oracle-instantclient11.2-basic-11.2.0.3.0-1.x86_64.rpm
  • 第二步,找出你的ORACLE_HOME,我安装之后在这里:/usr/lib/oracle/11.2/client64/lib/

  • 第三步,下载oracle-instantclient11.2-sdk-11.2.0.1.0-1.x86_64.zip 下载地址。解压,把里面那个叫sdk的文件夹复制到 /usr/lib/oracle/11.2/client64/lib/

  • 第四步,做一个软链:

1
2
$ cd /usr/lib/oracle/11.2/client64/lib/
$ ln -s libclntsh.so.11.1 libclntsh.so
  • 第五步,安装cx_Oracle:
1
2
3
$ export ORACLE_HOME=/usr/lib/oracle/11.2/client64/lib
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME
$ easy_install cx_Oracle
  • 试一下:
1
2
$ python
$ import cx_Oracle
done.
  • 不过还没配环境变量,一退再进去就不行了,在.bashrc里加入刚才安装之前的那两句:
1
2
3
4
5
$cd vim ~/.bashrc
export ORACLE_HOME=/usr/lib/oracle/11.2/client64/lib
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME

source ~/.bashrc

1.1.2 问题2:上述问题解决后出现“cx_Oracle.DatabaseError: Error while trying to retrieve text for error ORA-01804”问题

解决方法(参考“https://blog.csdn.net/zklth/article/details/7184032)”:

1
2
注释掉
os.environ["LD_LIBRARY_PATH"] = '$LD_LIBRARY_PATH:$ORACLE_HOME:$ORACLE_HOME'

出现新问题 “cx_Oracle连接数据库错误ORA-21561: 生成 OID 失败”

解决方法:参考“https://www.rookiefly.cn/detail/161”

1
2
3
4
修改本机hostname名称,然后终于成功
cat /etc/hosts
127.0.0.1 localhost redhat6
::1 localhost redhat6

1.1.3 问题3:数据库可以访问后出现 “from numpy.testing import nosetester ImportError: cannot import name ‘nosetester’”问题

问题原因:当前安装在python3.5.2的numpy版本和pandas版本冲突,修改版本
可用版本:

1
2
numpy (1.11.1)
pandas (0.18.1)

1.1.4 问题4:打包报错“ File “sklearn/metrics/pairwise_fast.pyx”, line 1, in init sklearn.metrics.pairwise_fast ImportError: No module named ‘sklearn.utils._cython_blas’”

问题原因:打包的时候无法自动加入sklearn包,手动添加即可

解决方法:在main.spec中的hiddenimports属性中手动添加

1
2
hiddenimports=['cython',  'sklearn', 'sklearn.utils._cython_blas','sklearn.neighbors.typedefs',
'sklearn.neighbors.quad_tree','sklearn.tree','sklearn.tree._utils'],

1.1.5 问题5:打包后运行然后又报问题2,“cx_Oracle.DatabaseError: Error while trying to retrieve text for error ORA-01804”

问题原因:缺少相关的oracle包

解决方法: 在main.spec中添加:

1
2
3
4
a.binaries = a.binaries + [('libclntsh.so', '/usr/lib/oracle/11.2/client64/lib/libclntsh.so.11.1','BINARY')]
a.binaries = a.binaries + [('libnnz11.so', '/usr/lib/oracle/11.2/client64/lib/libnnz11.so','BINARY')]
a.binaries = a.binaries + [('libocci.so', '/usr/lib/oracle/11.2/client64/lib/libocci.so.11.1','BINARY')]
a.binaries = a.binaries + [('libociicus.so', '/usr/lib/oracle/11.2/client64/lib/libociicus.so','BINARY')]

1.1.6 问题6:添加上述包之后出现“Oracle returned an error. ORA-12737: Instant Client Light: unsupported server character set SIMPLIFIED CHINESE_CHINA.UTF8 ”

问题原因: 见(https://thwack.solarwinds.com/t5/SAM-Discussions/Oracle-returned-an-error-ORA-12737-Instant-Client-Light/td-p/356034)
https://www.cnblogs.com/chenjianhong/p/4144399.html

在Instant Client Light中,语言只能是美国语言,地区可以是任何受支持的地区,字符集可以是以下任意一项:

■ 单字节

US7ASCII
WE8DEC
WE8MSWIN1252
WE8ISO8859P1
■ 统一码

UTF8
AL16UTF16
AL32UTF8
指定除列出为客户端或服务器字符集的字符集或国家字符集以外的字符集或国家字符集,或者在客户端上以NLS_LANG设置语言时,将引发以下错误之一:

  • ■ ORA-12734
  • ■ ORA-12735
  • ■ ORA-12736
  • ■ ORA-12737

使用Instant Client Light,获得的错误消息仅是英文的。因此,NLS_LANG设置的有效值的类型为:American_territory.characterset ,其中,region可以是任何有效且受支持的领域,并且characterset可以

可以是前面列出的任何字符集。Instant Client Light可以与在OCI_UTF16模式下创建的OCI环境句柄一起使用。

解决方法:
修改文字编码:

1
将os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8'  修改为os.environ['NLS_LANG'] = 'AMERICAN_AMERICA.AL32UTF8'

2.最终打包成功样例

步骤0:下载oracle客户端驱动文件

1
2
3
4
5
instantclient-sdk-linux.x64-11.2.0.4.0_2
instantclient-basic-linux.x64-11.2.0.4.0
# basic中要包含libclntsh.so,libnnz11.so,libocci.so,libociicus.so这四个文件
# 如果没有从instantclient-basiclite-linux.x64-11.2.0.4.0包中找
# 官方下载链接“https://www.oracle.com/database/technologies/instant-client/downloads.html”

步骤1:添加依赖链接在main.spec中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
main.spec: pyinstaller打包的说明文件,里面编写一些打包的时候手动添加的文件

# -*- mode: python ; coding: utf-8 -*-

block_cipher = None

a = Analysis(['main.py'],
pathex=['/home/redhat/Desktop/monthPredict'],
datas=[],
hiddenimports=['cython', 'sklearn', 'sklearn.utils._cython_blas','sklearn.neighbors.typedefs',
'sklearn.neighbors.quad_tree','sklearn.tree','sklearn.tree._utils'],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)

a.binaries = a.binaries + [('libclntsh.so', '/usr/lib/oracle/11.2/client64/lib/libclntsh.so.11.1','BINARY')]
a.binaries = a.binaries + [('libnnz11.so', '/usr/lib/oracle/11.2/client64/lib/libnnz11.so','BINARY')]
a.binaries = a.binaries + [('libocci.so', '/usr/lib/oracle/11.2/client64/lib/libocci.so.11.1','BINARY')]
a.binaries = a.binaries + [('libociicus.so', '/usr/lib/oracle/11.2/client64/lib/libociicus.so','BINARY')]

pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='main',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True )

步骤2:打包

1
使用 pyinstaller  main.spec 命令打包