Python基础入门自学——19--访问数据库

Posted kaoa000

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python基础入门自学——19--访问数据库相关的知识,希望对你有一定的参考价值。

继续前面的工作需求解决:

具体项目3:对于每个单位的考核结果进行分析,如果连续2个月出现红牌,要给与警告,连续3个月及以上的,要处罚,我们要实现的就是给出提示,连续2次出现红牌的月份,连续3次出现红牌的月份,等等。如下表,使用excel能够生成O列的分析串,我们要解决的就是找出串中出现的连续2个1及以上的的子串,然后分析出月份,给出提示。假设10名以后为红牌。

 解决思路:因为是要在一个字符串中查找一个变化的字符子串,而且结果不止一个,这时想到使用正则表达式来解决,要查找的串就是一个正则表达式,因为是找连续的1,用正则就是1{2,},代表查找连续2个及以上的1子串。

模拟数据:

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import openpyxl
import re

destfile = '考核汇总表.xlsx'

wb = openpyxl.load_workbook(destfile,data_only=True)
ws = wb['Sheet3']    #要分析的数据放在Sheet3工作表中

cellrange = ws['O3:O22']    #要分析的数据范围,因为这种分析数据范围都是固定的,可以直接写死
rownum = 3   #数据的起始行号
results = []   #分析结果保存在此列表

for cell_tmp in cellrange:
    start_pos = 0
    results_tmp = []
    cell_value = cell_tmp[0].value  #取要分析的单元格的值,即获得分析标志串
                                    #注意,cellrange是((),(),()。。。)形式,cell_tmp也是元组
    find_s = re.findall('1{2,}',cell_value)   #查找一个标志串中全部符合的子串
    # 注意find_s是子串的一个列表,形式如['111','11','11',。。。]
    # 我们需要的不是子串,而是子串的起始位置以及子串长度,以此来计算连续红牌的月份
    # 下面进行分析获得需要的信息
    if len(find_s) == 0:
        rownum += 1      # 无论是否找到子串,行号都要顺次往下走,即+1
        continue         # 当前没有找到符合的子串,跳过,继续下一次查找

    results_tmp.append(rownum)   # 如果找到符合子串,先将其行号保存
    for k in find_s:
        pattern = re.compile(k)
        pos_t = pattern.search(cell_value,start_pos)
        results_tmp.append(pos_t.span()[0])
        results_tmp.append(len(k))
        start_pos = pos_t.span()[0] + len(k)
    # for语句主要是对找到的子串进行遍历,找到其在标志串中的位置和长度
    # 如子串为['111','11'],找到111的起始位置,假如为1,子串长度3,11的起始位置6,长度2
    results.append(results_tmp)
    rownum += 1

print(results)

for result in results:
    m = 1
    ss = ''
    while m < len(result):
        ss = ss + str(result[m] + 1) + '月份开始,连续' + str(result[m+1]) + '个月红牌 |'
        m += 2
    ws['P' + str(result[0])] = ss

wb.save(destfile)
wb.close()

 运行结果:

 

 个人总结:因为对正则表达式不是很熟,一开始觉得应该有一个函数能够一下找出所有要查找的子串并给出每个子串的开始索引,结果没找到这样的函数,于是就想办法实现这个功能。

警告:要避免一个大坑,因为我的分析标志串是通过公式自动计算出来的,要使用python进行处理,就要获得单元格的值,而不是公式,所以在打开文件时,使用了data_only=True这个选项, 

wb = openpyxl.load_workbook(destfile,data_only=True)

结果处理完毕后,我这个excel文件中所有的公式全部被值取代了,一些需要公式来自动完成的功能全没了,几个周的结果全毁了,欲哭无泪啊!!!

好在处理前做过备份,所以做开发测试时一定要做备份!!!

openpyxl在处理excel还是有弱点的,因为我们取单元格的值,有时要取值,有时要取公式,而openpyxl控制粒度太大,只能在整个文件范围控制,并且中间不能改变,所以处理的文件最好就是做中间的过渡文件。

基本上,学习编程都要学习访问数据库。

几种主要的关系数据库:

Oracle,典型的高富帅;
SQL Server,微软自家产品,Windows定制专款;
DB2,IBM的产品,听起来挺高端;
Sybase,曾经跟微软是好基友,后来关系破裂,现在家境惨淡。

免费的开源数据库:

mysql,大家都在用,一般错不了;
PostgreSQL,学术气息有点重,其实挺不错,但知名度没有MySQL高;
sqlite,嵌入式数据库,适合桌面和移动应用。

 一、使用SQLite数据库

SQLite是一种嵌入式数据库,它的数据库就是一个文件。由于SQLite体积很小,经常被集成到各种应用程序中,甚至在iosandroid的App中都可以集成。

Python就内置了SQLite3,所以,在Python中使用SQLite,不需要安装任何东西,直接使用

几个概念:

表是数据库中存放关系数据的集合,一个数据库里面通常都包含多个表,比如学生的表,班级的表,学校的表,等等。表和表之间通过外键关联。

要操作关系数据库,首先需要连接到数据库,一个数据库连接称为Connection

连接到数据库后,需要打开游标,称之为Cursor,通过Cursor执行SQL语句,然后,获得执行结果。

Python定义了一套操作数据库的API接口,任何数据库要连接到Python,只需要提供符合Python标准的数据库驱动即可。

由于SQLite的驱动内置在Python标准库中,所以可以直接来操作SQLite数据库。

连接数据库后查询

 

 使用Python的DB-API时,只要搞清楚Connection和Cursor对象,打开后一定记得关闭,就可以放心地使用。
使用Cursor对象执行insert,update,delete语句时,执行结果由rowcount返回影响的行数,就可以拿到执行结果。
使用Cursor对象执行select语句时,通过fetchall()可以拿到结果集。结果集是一个list,每个元素都是一个tuple,对应一行记录。
如果SQL语句带有参数,那么需要把参数按照位置传递给execute()方法,有几个?占位符就必须对应几个参数,例如:
cursor.execute('select * from user where name=? and pwd=?', ('abc', 'password'))

在Python中操作数据库时,要先导入数据库对应的驱动,然后,通过Connection对象和Cursor对象操作数据。要确保打开的Connection对象和Cursor对象都正确地被关闭,否则,资源就会泄露。保证关闭使用try:...except:...finally:...方法。

二、配置连接oracle数据库

1、oracle客户端软件的安装

对于一个干净的客户端,在安装好Python后,要连接Oracle数据库,要先安装Oracle的instantclient,不同的操作系统有不同的版本,我的系统是win7 64位,测试数据库是Oracle11g,我选择的instantclient为:instantclient-basic-win-x86-64-11.2.0.1.0.zip。

解压缩到D盘:

 

在“环境变量”的“系统变量”中增加:

ORACLE_HOME = D:\\oracle11gclient\\instantclient_11_2 (网上说需要,但是测试不加也可以)

TNS_ADMIN = D:\\oracle11gclient\\instantclient_11_2(网上说需要,但是测试不加也可以)
NLS_LANG = SIMPLIFIED CHINESE_CHINA.ZHS16GBK
修改Path变量,在后面添加 D:\\oracle11gclient\\instantclient_11_2

然后把解压包中的oci.dll文件放到%python_home%\\Lib\\site-packages 下

2、Python中导入oracle的包,即cx_Oracle,我下载的如下:

cx_Oracle-8.2.1-cp39-cp39-win_amd64.whl试一下这个最新的版本。

出现问题:

升级pip:

 再次安装:

我的Python: 

 重新下载安装:

然后明白了: 

 同样在pycharm下不好用,在pycharm中的terminal中:

 需要先把cx_Oracle-8.2.1-cp38-cp38-win_amd64.whl拷贝到当前目录下。

然后写代码测试:

 可以带出来了,包导入成功。

测试:

 一开始运行,出现DatabaseError: DPI-1072: the Oracle Client library version is unsupported,查找网上资料,进行如下解决:

在pycharm的terminal中:

然后将

 

 三个文件拷贝到D:\\pythoncode\\projectz\\venv\\Lib\\site-packages目录下,然后问题就解决了

运行又出错:

 

成功。修改了一下,

 使用dsn的方式连接错误:

 问题找到,我的安装的Oracle服务器的SID是ORCLSID,然后数据库名用了orclzdy,对于Oracle连接,con = cx_Oracle.connect('system/zdy1234@//192.168.71.132:1521/orclzdy')是轻连接,端口后面跟的是数据库名称,使用con = cx_Oracle.connect(username,password,dsn),形成dsn的SID是ORCLSID。(因为对数据库不是很熟悉,安装时为了测试胡乱设置的,正常应该名字一致)

连接成功后就是数据库操作了,增删改查。

 使用oracle的tnsnames.ora中的配置连接数据库:

在安装的instantclient目录下,这里是D:\\oracle11gclient\\instantclient_11_2下建立NETWORK\\ADMIN目录,然后建立tnsnames.ora文件,

 

 都能成功连接。

以不同的角色登录,如我想sys用户以sysdba的角色登录:

con = cx_Oracle.connect('sys/zdy1234@TESTTNS',mode=cx_Oracle.SYSDBA)

连接Oracle数据库的三种方式:

三、配置MySQL数据库连接

MySQL是Web世界中使用最广泛的数据库服务器。SQLite的特点是轻量级、可嵌入,但不能承受高并发访问,适合桌面和移动应用。而MySQL是为服务器端设计的数据库,能承受高并发访问,同时占用的内存也远远大于SQLite。

1、获得MySQL数据库服务器

这个属于数据库服务器的安装,可以在网上查找。

2、安装MySQL驱动

由于MySQL服务器以独立的进程运行,并通过网络对外服务,所以,需要支持Python的MySQL驱动来连接到MySQL服务器。MySQL官方提供了mysql-connector-python驱动。

因为现在还没用到MySQL数据库,并且MySQL是使用最广泛的数据库,其Python支持应该做的很好,安装配置应该很简单,以后用到再学习了。

 

 

 

以上是关于Python基础入门自学——19--访问数据库的主要内容,如果未能解决你的问题,请参考以下文章

Python基础入门自学——22--异步IO

如何把Python入门?

Python自学从入门到就业之函数基础(小白必看)

零基础入门自学Python分为五个阶段

自学python需要安装什么软件-零基础入门Python怎么学习?老男孩python用什么软件...

Python基础入门自学——17--图形界面网络编程