我的编程空间,编程开发者的网络收藏夹
学习永远不晚

java调用python的惨痛史(无法获

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

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都能实现!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

java调用python的惨痛史(无法获

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

java调用python的惨痛史(无法获

环境:java,was,python2.6,红帽linux,oracle,python用cx_Oracle        事情是这样的,有个需求,需要对数据库进行处理,简单说就是把数据取出来,用python使用外部传参做一个处理,再写回到数
2023-01-30

python中无法调用numpy的原因有哪些

1. 未正确安装NumPy库:如果没有正确安装NumPy库,就无法在Python中调用它的功能。2. 忘记导入NumPy模块:在Python中,必须先导入NumPy模块,然后才能使用它提供的功能。如果忘记导入NumPy模块,就无法调用它的功
2023-09-08

python调用接口获取数据的方法是什么

在Python中调用接口获取数据的方法有几种:1. 使用内置的`urllib`或`urllib2`模块进行接口调用。这些模块提供了HTTP请求的基本功能,可以发送HTTP请求并获取返回的数据。示例:```pythonimport urlli
2023-08-29

Python实现调用jar或执行java代码的方法详解

这篇文章主要介绍了Python实现调用jar或执行java代码的方法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2022-12-21

Java如何规定在遇到无法解析的实体名称(NDATA)声明时被调用的函数

Java提供了两个函数来处理无法解析的实体名称(NDATA)声明:resolveEntity:解析具有指定公共标识符和系统标识符的实体。parse:解析具有指定系统标识符的文档。无法解析NDATA的原因可能包括:公共标识符或系统标识符不正确实体不可用文档格式错误Java提供了ErrorHandler接口和setEntityResolver方法来处理NDATA声明。
Java如何规定在遇到无法解析的实体名称(NDATA)声明时被调用的函数
2024-04-02

Python如何规定在遇到无法解析的实体名称(NDATA)声明时被调用的函数

Python规定遇到无法解析的实体名称声明(NDATA)时调用getattr方法。该方法返回属性值或引发AttributeError。NDATA声明是指对未定义名称的引用,可以通过getattr动态创建和访问属性。使用getattr有利于动态属性访问、属性延迟加载和对象扩展,但可能导致性能开销、调试困难和可读性降低。最佳实践包括仅在必要时使用、明确定义默认值、使用缓存和类型提示。
Python如何规定在遇到无法解析的实体名称(NDATA)声明时被调用的函数
2024-04-02

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录