java调用python的惨痛史(无法获取环境变量)
环境:java,was,python2.6,红帽linux,oracle,python用cx_Oracle
事情是这样的,有个需求,需要对数据库进行处理,简单说就是把数据取出来,用python使用外部传参做一个处理,再写回到数据库。如果使用java直接搞的话需要绕很大一个圈,比较麻烦,用python的话就很简单了,于是就有了下面的故事,希望和我遇到同样问题的同学能对你们有一些帮助,少绕一些圈子,java和python功能开发都很顺利,于是到了java调用python环节
大概把需要用到的功能写两个脚本,一个是用于连接数据库的,一个是用来实现功能的,方便后面说明
dbconn.py 这个用来连接数据库
- #!/usr/bin/python
- # coding: UTF-8
- import cx_Oracle
- def ora_conn():
- user_name = 'user'
- passwd = 'pass'
- host = 'localhost/orcl'
- conn = cx_Oracle()
- return conn
case.py 这个用来加工数据
- '''
- 接收传入参数
- 使用传入参数作为where条件到oracle中进行查找
- 对数据进行处理
- 写回到oracle
- '''
- #!/usr/bin/python
- # coding: UTF-8
- import os
- import sys
- #尝试获取环境变量my_home
- my_home = os.getenv('my_home')
- if not my_home:
- my_home = '/home/user_name'
- #cx_Oracle脚本是放在pypk目录里的,因此需要增加这个地方
- sys.path.append('%s/pypk' %my_home)
- import dbconn
- #接收参数,为了防止后面因为手误将此变量变更这里用global声明下全局,可有可无
- global out_into
- out_into = sys.argv[1]
- #获取数据库数据
- def get_data():
- print 'get data'
- conn = dbconn.ora_conn()
- conn_cur = conn.cursor()
- sql = 'select col1,col2 from tablename where col1 = %r' %out_into
- data_values = conn_cur.execute(sql)
- result = list(data_values)
- conn_cur.close()
- conn.close()
- return result
- #处理,为了方便,假设就是在col1前面加a和col2前面加b,然后拼在一起用;分隔
- def manage_data(values):
- print 'manage data'
- col1 = 'a' + str(values[0])
- col2 = 'b' + str(values[1])
- col_return = col1 + ';' + col2
- return col_return
- #写入数据库d
- def into_data(into_values):
- print 'insert into data'
- conn = dbconn.ora_conn()
- conn_cur = conn.cursor()
- sql = 'insert into result_table(col) values(%r)' %into_values
- conn_cur.execute(sql)
- conn.commit()
- conn_cur.close()
- conn.close()
- def main():
- print 'run start'
- datas = get_data()
- for line in datas:
- ok_values = manage_data(line)
- into_data(ok_values)
- if __name__ == '__main__':
- main()
- exit()
因为不知道java调用效果怎样,先写了个简单的python脚本用java调用测试了下
test.py 这个只是用来测试功能,所以只有一行代码
- print 'hello'
测试成功,这里因为这边没有环境,就不截图了,大家凑合看吧。又加入两行,测试了一下传参
test.py
- print 'hello'
- a = sys.argv[1]
- print a
一样成功了,信心满满的上正式脚本来测试,正常打印了脚本中的内容
run start
get data
manage data
insert into data
去数据库里面查,结果目标表result_table没有数据。我擦,这什么鬼,没报错也没有处理,完全没有头绪,尝试加上try看看有没有什么帮助。于是case.py的main函数就变成了下面这样
- def main():
- print 'run start'
- try:
- datas = get_data()
- for line in datas:
- ok_values = manage_data(line)
- into_data(ok_values)
- except Exception, e:
- print e
这次果然有结果了,cx_Oracle连接失败,缺少libclntsh.so.11.1,这里着重说明下,网上都是win调用cx_Oracle的,需要拷贝什么dll,这个在linux中是没用的,而且就算是win也不是像上面说的那样把一堆dll拷贝到脚本当前目录里面,这样只是治标不治本。
正确的方法是加三个环境变量
- export ORACLE_HOME=oracle_install_path #第一个当然是ORACLE_HOME
- export PATH=$PATH:$ORACLE_HOME/bin #第二个是bin
- export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME/lib #第三个是lib
我不想留坑,建议这三个变量加到~/.bashrc里面,不过这个并没有解决根本问题,后面会说明,请各位继续往下看
加入环境变量以后又执行了下,报错connect to Oracle Database,尼玛犬加上了啊,于是在本地linux服务器执行了下,结果。。。。。。正常执行,完全问题,这次真是见鬼了啊。某楠说的好,真相只有一个,特么就不信了,我倒要看看是出什么问题了,根据以往经验,环境变量加失败的话可能是使用用户和加环境变量的用户不一致,于是在case.py里面加上一段
- import getpass
- now_user = getpass.getuser() #用来获取当前操作用户
- print now_user
结果是root,对啊,是root啊,而且我也是SB了,.bashrc这个不是应该全局的么,就是全部用户通用的环境变量啊。算了,死马当活马医,倒要看看环境变量里都是什么玩意,在case.py里面再加一行
- os.system('env') #调用linux的外部命令,查看全部环境变量
然后,意外出现了,打印出来的环境变量里面根本就没有加入的三个环境变量,而且大部分都不是linux里面的环境变量,好多都是was用的,难道是was有自己的环境变量么,问了下同事,果然坑啊,真的有自己的环境变量配置。这下问题找到了,那么解决办法就是把这三个加到was自有的环境变量里面就好了嘛,于是。。。。。。在was里加入了ORACLE_HOME、PATH、LD_LIBRARY_PATH这三个环境变量。
重新测试下,尼玛刚才加入的居然不在里面,这就尴尬了,怎么办。。。怎么办。。。在分针从12绕到11的时候,终于,办法有了,把环境变量作为外部命令加进去不就行了,继续在case.py中加入三行
- os.system(export ORACLE_HOME=oracle_install_path)
- os.system(export PATH=$PATH:$ORACLE_HOME/bin)
- os.system(export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME/lib)
这时候我都快成福尔摩斯了,感觉已经超越某楠了有木有,但是事实仍然给了我当头一棒,失败了,打印出来的环境变量里这三个依然不存在的,原因是这样加入的环境变量不会直接有效的,需要注销才可以生效,简直崩溃了,然后分针又默默的从12走到了11。突然灵感一现,如果用python自有的加环境变量的方法能不能绕过注销这个步骤呢,说弄就弄,于是将case.py中的
- os.system(export ORACLE_HOME=oracle_install_path)
- os.system(export PATH=$PATH:$ORACLE_HOME/bin)
- os.system(export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME/lib)
替换成下面的
- oracle_home_env = [['ORACLE_HOME','oracle_install_path'],['PATH','$PATH:$ORACLE_HOME/bin'],['LD_LIBRARY_PATH','$LD_LIBRARY_PATH:$ORACLE_HOME/lib']]
- for env_line in oracle_home_env:
- os.environ[env_line[0]] = env_line[1]
好吧,我承认,这个办法不是我想出来的,能相出这种加环境变量方法的人真是大神啊
继续我们的故事,然后,奇迹出现了,这三个环境变量终于在打印的结果中出现了,但是依然报错连接不上数据库,不过这就好办了,既然这个环境变量指向的linux,那只要用linux的方法调用脚本就好了嘛。说弄就弄,新加了一个脚本,用来调用case.py,只有几行
call_script.py 用来使用外部命令调用case.py
- #!/usr/bin/python
- # coding: UTF-8
- import os
- out_into = sys.argv[1]
- my_home = os.getenv('my_home')
- if not my_home:
- my_home = '/home/user_name'
- os.system('python %s/case.py %s' %(my_home,out_into))
到这里故事就结束了,不过就像大部分剧本一样,总要有彩蛋嘛哈哈
以为这样就结束了么?当然不是,有没有看到my_home,这个也是一个环境变量!这里没有报错的原因是因为在下面加入了一个if,如果没有获取到的话默认/home/user_name,但是路径换了呢?这一路升级的,感觉小棍子都能升级到金箍棒了,这点小事还搞不定么,好了,不说了,我要去吃点什么庆祝了。
春节了,一年了,终于等到这一天了,能看到这个文也算是缘分,在这里就祝大家在新的一年里 多多赚钱、少一些坑、身体健健康康、立的flag都能实现!
java调用python的惨痛史(无法获取环境变量)的更多相关文章
- Java 调用python说明文档
Java 调用python说明文档 通过java调用python脚本主要如下三种方式: 1.直接执行python脚本: 2.执行python.py文件: 3.使用Runtime.getRuntime( ...
- (转)java调用python脚本
这篇博客旨在吐血分享今天遇到的java调用python脚本遇到的坑,折腾了3个多小时终于可以跑通了,代码超级短,但网上的好多资料都是抄来抄去的,很少有能够直接跑通的,尤其是针对你的python文件中用 ...
- Java调用Python相关问题:指定python环境、传入参数、返回结果
本篇文章涉及到的操作均在Windows系统下进行,Java调用python在原理上不难,但是可能在实际应用中会有各种各样的需求,网上其他的资料很不全,所以又总结了这篇文章,以供参考. 一.指定pyth ...
- 通过Java调用Python脚本
在进行开发的过程中,偶尔会遇到需要使用Java调用Python脚本的时候,毕竟Python在诸如爬虫,以及科学计算等方面具有天然的优势.最近在工作中遇到需要在Java程序中调用已经写好的Python程 ...
- Python一键转Jar包,Java调用Python新姿势!
粉丝朋友们,不知道大家看故事看腻了没(要是没腻可一定留言告诉我^_^),今天这篇文章换换口味,正经的来写写技术文.言归正传,咱们开始吧! 本文结构: 需求背景 进击的Python Java和Pytho ...
- java调用python程序以及向python程序传递参数
在做项目的时候,经常会碰到这个问题,主要程序是用java写的,有些功能使用python写的,整个项目需要把java代码和python代码进行整合,在一个项目里面运行,这就涉及到java调用python ...
- java调用python脚本并向python脚本传递参数
1.安装Eclipse 先安装jdk,再安装Eclipse,成功后开始建立py_java项目,在这个项目的存储目录SRC下建立test包,在test包中New-Class,新建MyDemo类,建好完成 ...
- [Java/Python] java调用python脚本问题记录
Java调用Python的的两种方式 1.Runtime private static String call_python(String input_argv) { String python_py ...
- Runtime.getRuntime().exec()实现Java调用python程序
使用Runtime.getRuntime().exec()来实现Java调用python,调用代码如下所示: import java.io.BufferedReader; import java.io ...
随机推荐
- 和我一起打造个简单搜索之Logstash实时同步建立索引
用过 Solr 的朋友都知道,Solr 可以直接在配置文件中配置数据库连接从而完成索引的同步创建,但是 ElasticSearch 本身并不具备这样的功能,那如何建立索引呢?方法其实很多,可以使用 J ...
- mysql格式化时间戳为日期
MySQL中有一个像PHP的date函数一样的日期格式化函数DATE_FORMAT,使用这个函数时,需要像下面例子这样传递一个格式字符串和时间戳 SELECT DATE_FORMAT(NOW(),&q ...
- Angular2入门:TypeScript的类型 - 类型、null、undefined
- Java基础之基础语法
前言:Java内功心法之基础语法,看完这篇你向Java大神的路上又迈出了一步(有什么问题或者需要资料可以联系我的扣扣:734999078) 一个Java程序可以认为是一系列对象的集合,而这些对象通过调 ...
- netty源码解解析(4.0)-12 Channel NIO实现:channel初始化
创建一个channel实例,并把它register到eventLoopGroup中之后,这个channel然后处于inactive状态,仍然是不可用的.只有在bind或connect方法调用成功之后才 ...
- tensorflow入门指南
TensorFlow是Google公司2015年11月开源的第二代深度学习框架,是第一代框架DistBelief的改进版本. TensorFlow支持python和c/c++语言, 可以在cpu或gp ...
- Java 使用 happen-before 规则实现共享变量的同步操作
前言 熟悉 Java 并发编程的都知道,JMM(Java 内存模型) 中的 happen-before(简称 hb)规则,该规则定义了 Java 多线程操作的有序性和可见性,防止了编译器重排序对程序结 ...
- 【转】 Apk文件及其编译过程
Apk文件概述 Android系统中的应用程序安装包都是以apk为后缀名,其实apk是Android Package的缩写,即android安装包. 注:apk包文件其实就是标准的zip文件,可以直接 ...
- 配置hadoop-eclipse-plugin(版本hadoop2.7.3):
配置hadoop-eclipse-plugin(版本hadoop2.7.3): 1:首先下载我们需要的 hadoop-eclipse-plugin-2.7.3.jar,winutils.exe 和 ...
- Vim settings file on Windows
Question: I can't believe I am typing a question for a simple thing like this but here we are. I can ...