数据库非常重要,程序的数据增删改查需要数据库支持。python处理数据库非常简单。而且不同类型的数据库处理逻辑方式大同小异。本文以`sqlite`数据库为例,介绍一下python操作数据库的方法。
在部署环境过程中,可以存在数据量级的改变,可以需要升级数据库并保留原有数据,sqlite和mysql无法很好的数据直接导出导出,需要通过中间脚本进行
python sqlite3 官方文档
pip install pysqlite3 -i https://pypi.douban.com/simple
import sqlite3
# 连接数据库(如果不存在则创建)
conn = sqlite3.connect('test.db')
print("Opened database successfully")
# 创建游标
cursor = conn.cursor()
# 关闭游标
cursor.close()
# 提交事物
conn.commit()
# 关闭连接
conn.close()
import sqlite3
conn = sqlite3.connect('test.db')
print ("数据库打开成功")
c = conn.cursor()
c.execute('''CREATE TABLE COMPANY
(ID INT PRIMARY KEY NOT NULL,
NAME TEXT NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR(50),
SALARY REAL);''')
print ("数据表创建成功")
conn.commit()
conn.close()
sql="select name from company where addrass='test' order by name"
tables=cursor.execute(sql).fetchall()
print(len(tables))
sql = f"INSERT INTO company (ID,NAME,AGE,ADDRESS,SALARY) \
VALUES (1,'test',25,'test','33')"
cursor.execute(sql)
sql="DROP TABLE database_name.table_name"
cursor.execute(sql)
**这是对row_factory的官方解释(官方解释直接忽略就好,看我下面的解释):**A Row instance serves as a highly optimized row_factory for Connection objects. It tries to mimic a tuple in most of its features.
It supports mapping access by column name and index, iteration, representation, equality testing and len().
If two Row objects have exactly the same columns and their members are equal, they compare equal.
基础Cursor
对象只能通过数字索引来获取值,但是我想通过列名来获取值是做不到的。虽然可以使用Cursor.description
来获取字段名称,但是自己做映射写代码很麻烦。
本着简约代码(懒)的原则,python推出了Cursor.Row
对象。其实就是列名和值做了个映射,可以通过字符索引来获取值。很方便。
升级过程也简单,就加一句话:conn_from.row_factory = sqlite3.Row
def dict_factory(cursor, row):
d = {}
for idx, col in enumerate(cursor.description):
d[col[0]] = row[idx]
return d
pip install pymysql -i https://pypi.douban.com/simple
import pymysql
# 连接数据库(如果不存在则创建)
conn = pymysql.connect(host='mysql',user='root', passwd='123456',db='test',port=3306)
print("Opened database successfully")
# 创建游标
cursor = conn.cursor()
# 关闭游标
cursor.close()
# 提交事物
conn.commit()
# 关闭连接
conn.close()
保持sqlite,mysql表结构一致,在建表的过程中,sqlite和mysql使用的
#! /usr/bin/python
# encoding:utf-8
import pymysql
import sqlite3
def dict_factory(cursor, row):
d = {}
for idx, col in enumerate(cursor.description):
d[col[0]] = row[idx]
return d
def convertDB(fromDict, toDict):
print(fromDict['connect_parameters'])
fromTableName= fromDict["tableName"]
if fromDict['type']=='sqlite':
#连接sqlite数据库
conn_from = sqlite3.connect(fromDict['connect_parameters'])
conn_from.row_factory = dict_factory
cur_from = conn_from.execute(f"select * from {fromTableName}")
from_list = cur_from.fetchall()
elif fromDict['type']=='mysql':
#连接mysql数据库
conn_from = pymysql.connect(host=fromDict['connect_parameters']['host'],
user=fromDict['connect_parameters']['username'],
passwd=fromDict['connect_parameters']['password'],
db=fromDict['connect_parameters']['dname'],
port=fromDict['connect_parameters']['port'])
conn_from.row_factory = dict_factory
cur_from=conn_from.cursor()
cur_from.execute(f"select * from {fromTableName}")
from_list=cur_from.fetchall()
if toDict['type']=='sqlite':
#连接sqlite数据库
conn_to = sqlite3.connect(toDict['connect_parameters'])
elif toDict['type']=='mysql':
#连接mysql数据库
conn_to = pymysql.connect(host=toDict['connect_parameters']['host'],
user=toDict['connect_parameters']['username'],
passwd=toDict['connect_parameters']['password'],
db=toDict['connect_parameters']['dname'],
port=toDict['connect_parameters']['port'])
toTableName= toDict["tableName"]
for item in from_list:
if toDict['type']=='sqlite':
# sql = f"INSERT INTO company (ID,NAME,AGE,ADDRESS,SALARY) \
# VALUES (?,?,?,?,?)"
keys = item.keys()
values = item.values()
key_str = ",".join(keys)
key_str_1 = ",".join([f'\'{value}\'' if isinstance(value,str) else f'{value}' for value in values])
# key_str_1 = ",".join([f'\'?\'' if isinstance(value,str) else '?' for value in values])
# key_str_1 = ",".join(['?' for value in values])
sql = f"INSERT INTO {toTableName} ({key_str}) VALUES ({key_str_1})"
print(sql)
elif toDict['type']=='mysql':
# sql = f"INSERT INTO company (ID,NAME,AGE,ADDRESS,SALARY) \
# VALUES (%s,%s,%s,%s,%s)"
keys = item.keys()
values = item.values()
key_str = ",".join(keys)
key_str_1 = ",".join([f'\'{value}\'' if isinstance(value,str) else f'{value}' if value else 'NULL' for value in values])
# key_str_1 = ",".join([f'\'%s\'' if isinstance(value,str) else '%s' for value in values])
# key_str_1 = ",".join(['%s' for value in values])
sql = f"INSERT INTO {toTableName} ({key_str}) VALUES ({key_str_1})"
print(sql)
cur_to=conn_to.cursor()
cur_to.execute(sql)
conn_to.commit()
db_path = "db.sqlite3"
for tableName in ['company']:
fromTableName = tableName.title()
toTableName = tableName
# 将sqlite数据库test转换到mysql
fromDict = {'type':'sqlite', 'connect_parameters' : db_path,'tableName':fromTableName}
toDict = {'type' : 'mysql', 'connect_parameters' : {'host':'mysql', 'username':'root', 'password':'test',
'port':3306, 'dname':'test'},'tableName':toTableName}
convertDB(fromDict,toDict)
# # 将mysql数据库转换到sqlite数据库test1
# fromDict = {'type' : 'mysql', 'connect_parameters' : {'host':'192.168.48.10', 'username':'test', 'password':'mysql',
# 'port':3306, 'dname':'test'}}
# toDict = {'type':'sqlite', 'connect_parameters' : 'D:/test1.db'}
# convertDB(fromDict,toDict)