python心得之sqlite数据库操作

python心得之sqlite数据库操作

前两天帮助LZM童鞋做了她们大创项目中的一丢丢,主要是将一些.dat文件中的内容筛选后做成数据库。一开始我只听她说这个进程一直很缓慢,然后我就随口一问她们用的是什么数据库,结果她说是sqlite。

原来是sqlite啊,想起当年sdn项目里用到的近10年的漏洞数据库,当时在网上找了一圈没找到那种可以下载下来直接调用的的,都是要在线查询,无奈只好选择自己实现一个。我记得我好像是从github上一个项目得到启发,于是乎去CVE(Common Vulnerabilities and Exposures)官网上找到了数据库的xml格式内容,然后用python脚本将其写到sqlite数据库中。好像有快10万个漏洞的信息吧,对应的数据库里有5张表,几十万条表项,跑了多久不记得我只记得反正是在我笔记本上跑的,跑得那叫一个天昏地暗。后来因为项目需求,又加了一张漏洞对应snort规则的表。最后得到的纯文本的漏洞数据库足足有180M,可想其内容。(想要这个数据库的联系我~) 

因为以前做过,所以我跟她说我可以帮忙,然后就接了锅。果然是有段时间没写python了,if总是忘加“:”,句尾总是多加“;”。但python就是python,蛇毒就是让人感觉“Yeah, that's it”!从接锅到写完代码,再到运行得到sqlite数据库,除去测试时间,前前后后也就花了1个小时左右,虽然她们的数据库本来就不大,也就几百K,但这次背锅还是再次让我体会到了python的妙处,尤其是在字符串处理方面。再加上python的各种各样的库,因此用python可以很方便地将各种格式的文本文件导入到数据库中。这种需求还是挺常见的:因为种种原因,开发者得到的数据文件通常不是可以直接拿来高效率使用的数据库,而是各种格式的文本文件,例如xml、json甚至包括纯文本文件(汗),而为了程序的需要,直接打开文本文件在其中搜索数据将会十分低效费时,所以通常会将文本文件中的数据转入到数据库中。接下来总结下用python应对这种需求的一般方法:

一、利用python对应的文本文件处理库导入文件

So what do I mean?其实就是在python中打开存有数据的文本文件。
举个例子,如果数据是以json格式存储到文本文件中,应该使用python的json库对其进行到入,如下:

import json
input = json.load(file("yours.json"))

 

至于python用哪些库如何处理对应格式的文本文件,可以google或baidu。总之,python的库只有你没用过,没有想不到。

二、使用python对读入的数据进行处理

这一步的目的就是要利用python强大的字符串处理能力对从文本文件中读入的数据作进一步处理,方便过后使用数据库相关指令对应数据进行操作。

队友PJW曾经说过,一个语言的强大可以提现在其对字符串处理上。从这个角度上来说,python确实是世界上最好的语言(哈哈,php程序员莫辩,玩笑之言),再次安利python,它的好,谁用谁知道。

三、使用python连接数据库并进行数据操作

我最喜欢用的数据是sqlite,具体原因我自己也说不上来。但据我所知,其应用相当广泛,尤其是被Android视为内置数据库。sqlite目前已经出到了第三版即sqlite3,它的命令跟mysql稍有区别,用习惯了mysql的童鞋可以选择一篇教程看看即可,核心概念和思想都是相通的。这里推荐个网站,我没次忘记都是去这里查的:http://www.runoob.com/sqlite/sqlite-tutorial.html细心的童鞋可能会发问:本篇博客不是在将如何利用python进行数据库操作嘛,上面的网址里全是数据库的命令啊?其原因就是在python中对数据库的操作,用的最多的就是使用数据库对象的execute方法直接执行数据库命令,明了方便,可以完全体现sqlite的语言灵活性,所以熟练掌握数据库命令是必需的。

对数据库的操作可以分为查询、插入、删除等,但对应的python语句基本一样,原因就是其execute方法将问题转化为数据库中的操作指令如何写。

插入、删除等改变数据库内容的数据操作的具体做法为:

import sqlite3
conn = sqlilte3.connect("database.db")

conn.execute(sqlite_instruction) 

conn.commit() 

查询等不改变数据库内容的数据操作的具体方法为:

import sqlite3
conn = sqlilte3.connect("database.db")

cursor = conn.execute(sqlite_instruction)

for row in cursor: 

#visit row[0], row[1].... 

注意对于插入、删除等,一定要调用commit方法才能使execute生效,就相当于git中的commit。对于查询等,返回结果通过execute的返回值cursor访问,cursor是查询结果的集合,每个元素对应数据库中的一个row。

好吧,上面是博主自己总结的,如有不对的地方,欢迎指正。最后,贴出博主为LZM写的代码,50行左右,算是为上面总结贴出个例子。

#!/usr/bin/env python
# coding=utf-8

import sqlite3
import glob     
# Traverse all files under the appointed dir

conn = sqlite3.connect("data.db");  
# Care: data.db is in the same path with this program

for file in glob.glob("./data/*.dat"):
    # Traverse all .dat file in ./data/
    contents = open(file, 'r').readlines()
    head = {};
    # head is a dictonary to record the ids of diverse rows
    id = 0;
    for item in contents[0].split("\t"):
        if (item == "T (C)"):
            head["temperature"] = id
        elif (item == "Density (g/(cm)^3)-TOTAL"):
            head["density"] = id
        elif ("Thermal conductivity (W/(m*K))" in item):
            head["thermal_conductivity"] = id
        elif ("Electrical resistivity (10e-6 Ohm*m)" in item):
            head["electrical_resistivity"] = id
        elif ("Electrical conductivity (10e6 1/(Ohm*m))" in item):
            head["electrical_conductivity"] = id
        elif ("Young's modulus (GPa)" in item):
            head["young_modulus"] = id
        elif ("Shear modulus(GPa)" in item):
            head["shear_modulus"] = id
        elif (item == "Poisson's ratio-TOTAL"):
            head["poisson_ratio"] = id
        elif (item == "Enthalpy (J/g)"):
            head["enthalpy"] = id
        id += 1
    name = file.replace(".dat", '')
    name = name.replace("./data/", '')
    # Deal with the file name, for example: "./data/20Mn-c.dat" => "20Mn-c"
    print(name)
    for row in contents[1:]:
        items = row.split("\t")
        cmd = '''insert into data(name, temperature, density, thermal_conductivity, 
            electrical_resistivity, electrical_conductivity, youngs_modulus, shear_modulus,
            poisson_ratio, enthalpy) 
            values("{0}", {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9})'''.format(
            name, 
            int(float((items[head["temperature"]]))),
            float(items[head["density"]]),
            float(items[head["thermal_conductivity"]]),
            float(items[head["electrical_resistivity"]]),
            float(items[head["electrical_conductivity"]]),
            float(items[head["young_modulus"]]),
            float(items[head["shear_modulus"]]),
            float(items[head["poisson_ratio"]]),
            float(items[head["enthalpy"]]))
        # Generate the sqlite instruction
        print(cmd)
        conn.execute(cmd)
        conn.commit()

其中,*.dat文件里记录的是某种材料在不同温度下的各种性质,*代表该材料的名字,里面的内容用Excel打开效果如下图所示:

本文到这里差不多介绍完了,但实际上python的sqlite3库里还有很多函数博主并没有提及,读者可以自己去查找和学习。

6 thoughts on “python心得之sqlite数据库操作

  1. wong

    讲真!看你的博客简直是一种挑战!不过我对这篇文章蛮有兴趣的!好像我们大创业需要数据处理但是那个软件好像是我们老师自己开发的,但是更多的好像需要建模什么鬼!我还没仔细研究

    1. dracula

      厉害! wong是你拼错了,还是故意的?

      1. wong

        没有啊,wong是我的姓啊!我发现之前用真名留言显得太silly 了

        1. dracula

          据说,wong是香港人的习惯,wang是大陆人的习惯

  2. xxiperona

    卧槽 我学java是不是太愚蠢了
    我是不是该学python

    1. dracula

      不啊,java也很强大,应用相当广泛。python终究还是个脚本语言。

Leave a Reply

电子邮件地址不会被公开。 必填项已用*标注