最近经常sql, 正常的数据一般没有问题,可是遇到了一个字段里嵌套了json,而我要取的内容偏偏在里面,这个时候再用sql,我觉得我肯定是脑抽了,于是就想用python取出数,在python里面操作
0x00 尝试
要操作oracle肯定需要相应的库,上网找找看。 - cx_Oracle oracle官方推荐, 这肯定是没错了。
pip install cx_Oracle
What!!! 报错了,说是缺少vc++, 这是什么鬼,没记错的话,之前装scrapy好像也遇到过。这个时候你以为我会再次用出上网搜索大法,错了,直接祭出神兵,https://www.lfd.uci.edu/~gohlke/pythonlibs/ . 什么时候python有装不了的库,先上这个网址试试,找到相应的库直接下载到本地安装:
pip install cx_Oracle-6.4.1-cp36-cp36m-win_amd64.whl
0x01 举个栗子
import cx_Oracle #导入包
db = cx_Oracle.connect('用户名','用户密码','ip:端口号/数据库名') #连接数据库
print(db.version) #打印版本看看 显示 11.2.0.1.0
cur = db.cursor() # 游标操作
cur.execute('select * from table') # 执行sql语句
rows = cur.fetchall() # 获取数据
# 打印数据
for row in rows[:10]:
print(f"{row[0]} ,",end='')
很好,可以正常取出数据。
0x02 怎么能用pandas
数据已经取出了,可是我如果要正常操作,处理好数据在存入数据库,这样操作好像不是太方便。我想到了最喜欢的pandas,能用pandas 操作吗? 打开pandas的ducment, IO tools里清楚的写着read_sql,这不是说可以读取数据库, 可是仔细一看,又多了一个库sqlalchemy, 这个业务我们不熟悉呀,怎么整?
0x03 熟悉sqlalchemy
既然不熟悉,好说,先安装下来,上代码走一遍: 安装包:
pip install sqlalchemy -i http://pypi.douban.com/simple --trusted-host pipy.douban.com
SQLAlchemy本身无法操作数据库,其必须以来cx_Oracle等第三方插件,Dialect用于和数据API进行交流,根据配置文件的不同调用不同的数据库API,从而实现对数据库的操作,如:
MySQL-Python
mysql+mysqldb://:@[:]/
pymysql
mysql+pymysql://:@/[?]
MySQL-Connector
mysql+mysqlconnector://:@[:]/
cx_Oracle
oracle+cx_oracle://user:pass@host:port/dbname[?key=value&key=value...]
这下,我们上面安装好的cx_Oracle又可以用了。 执行原生sql试试:
from sqlalchemy import create_engine # 导入包
engine = create_engine('oracle+cx_oracle://user:pass@host:port/dbname') # 创建连接引擎
conn = engine.connect() # 连接数据库
res = conn.execute('select * from table') # 执行sql
res = res.fetchall() # 获取所有数据,这里返回的是list
print(res[:5]) #查看前5个数据
P.S: 这里有两个坑,平时在navicat里看到的表名都是全大写的,因些在python里写的时候也只然写成大写了,结果竟然出错,要写成小写才成功,这里没有探究是什么原因,猜测是python区分大小写,数据库还是navicat没有区分,还有一个是cx_oracle的锅,中文识别会出现乱码
中文乱码的解决方案:
在python脚本中加入这几句:
# -*- coding: utf-8 -*-
import os
os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8'
这下又天下太平了。
0x04 回到pandas
经历了sqlalchemy, 终于大概知道是怎么回事了,现在不影响我们使用pandas了,我们再次尝试pandas的用法。
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# 导入包
import os
from sqlalchemy import create_engine
import pandas as pd
os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8'
# 同样的套路,创建连接引擎
engine = create_engine('oracle+cx_oracle://user:pass@host:port/dbname')
# with管理安全
with engine.connect() as conn, conn.begin():
# 直接给出要查的表名,sql原生语句都不用写了
data = pd.read_sql_table('table_name', conn)
print(data.head()) # 查看前5个数据
返回结果:
0x05 处理json
数据已经拿到了,接下来就是我们的初衷了,处理那串json, 获取我们需要的内容:
# 导入包
import json
# 定义函数,获取所需内容
def get_table_name(el):
return json.loads(el)['front_formmain']['tableName']
data['table_name'] = data['field_info'].map(get_table_name)
查看结果:
我们成功的获得了所需数据,接下是存储为csv还是存入数据库就看需求了。