python实战之操作数据库基础
熟悉python的常见数据结构
Python 提供了几种内置的数据结构,用于组织和存储数据。以下是一些常见的Python数据结构:
列表(List):
-
有序的可变序列。
-
用于存储一组元素。
-
my_list = [1, 2, 3, 'hello']
元组(Tuple):
-
有序的不可变序列。
-
用于存储一组元素,但一旦创建就不能修改。
-
my_tuple = (1, 2, 3, 'hello','world')
集合(Set):
-
无序的可变容器,不允许重复元素。
-
用于进行集合操作,如并集、交集等。
-
my_set = {1, 2, 3, 4}
字典(Dictionary):
-
无序的键值对集合。
-
用于存储和检索数据,每个键对应一个值。
-
my_dict = {'name': 'John', 'age': 30, 'city': 'New York'}
字符串(String):
-
有序的字符序列。
-
用于存储文本数据。
-
my_string = "Hello, World!"
队列(Queue):
-
通过
queue
模块提供的数据结构。 -
用于实现先进先出(FIFO)的数据结构。
-
import queue; my_queue = queue.Queue()
堆栈(Stack):
-
通过
collections
模块提供的deque
实现。 -
用于实现后进先出(LIFO)的数据结构。
-
from collections import deque; my_stack = deque()
字节序列(Bytes):
-
不可变的字节序列。
-
用于处理二进制数据。
-
my_bytes = b'Hello'
常见数据结构的操作
在Python中,常见的数据结构包括列表(List)、元组(Tuple)、集合(Set)、字典(Dictionary)等。以下是这些数据结构的一些常见操作:
列表(List):有序可变
-
访问元素:通过索引访问列表中的元素,例如
my_list[0]
。my_list = [1,2,3,4,5]#创建列表 your_list = ['a','b','c']#创建列表 a = my_lsit[0] print(a)#A 在Python中,当你使用 print() 函数打印一个字符串时,Python会将字符串的值打印出来,而不是字符串的表示形式(包括引号)。这是Python的一种约定,使得输出更加清晰和简洁。 所以,当你打印字符串 'A' 时,输出的内容会是字符 A,而不是带有引号的 'A'。这并不影响字符串在程序中的使用,只是在输出时省略了引号,使输出更加直观
-
添加元素:使用
append()
方法在列表末尾添加元素,使用insert()
方法在指定位置插入元素。my_list = [1,2,3,4,5]#创建列表 your_list = ['a','b','c']#创建列表 my_list.append(your_list)#添加元素,将整个元素打包放到末尾 my_list.insert(0,'A')#0号位置添加一个'A' print(my_lsit) #输出结果:['A', 1, 2, 3, 4, 5, ['a', 'b', 'c']]
-
删除元素:使用
remove()
方法删除指定值的元素,使用pop()
方法删除指定位置的元素。#创建列表 my_list = [0,1,2,3,4,5] your_list = ['a','b','c',4,3] my_list.remove(2)#删除list含有的值,不是index print(my_list)#[0,1,3,4,5] your_list.pop(3) print(your_list)#['a','b','c',3]
-
切片操作:可以通过切片来获取列表的子集,例如
my_list[start:end]
。my_list = [1, 2, 3, 4, 5] # 获取索引为1到3的子集(不包含索引为3的元素) sub_list = my_list[1:3] print(sub_list) # 输出: [2, 3] # 获取从索引为0到末尾的子集 sub_list = my_list[0:] print(sub_list) # 输出: [1, 2, 3, 4, 5] # 获取从索引为2到末尾的子集,步长为2 sub_list = my_list[2::2] print(sub_list) # 输出: [3, 5]
-
合并列表:使用
+
运算符或extend()
方法将两个列表合并。#使用 + 运算符: 运算符重载:+ 运算符被重载用于列表合并操作,这使得代码更加简洁和直观。 创建新列表:使用 + 运算符创建了一个新的列表对象,原始列表不受影响。 适用性:适用于合并少量的列表或在需要创建新列表的情况下使用。 #使用 extend() 方法: 就地修改:extend() 方法直接在原列表上进行修改,而不是创建新的列表对象。 原地操作:这种方法更节省内存,因为不会创建新的列表对象,而是直接修改了原列表。 适用性:适用于合并大量列表或在不需要创建新列表的情况下使用,以节省内存和提高效率。 总的来说,如果你想保持原始列表不变,并且合并的列表数量较少,使用 + 运算符更为方便;如果你需要在原列表上就地修改,并且合并的列表数量较大,使用 extend() 方法更为高效。 list1 = [1, 2, 3] list2 = [4, 5, 6] list1.extend(list2) print(list1) # 输出: [1, 2, 3, 4, 5, 6]
元组(Tuple):
-
访问元素:通过索引访问元组中的元素,例如
my_tuple[0]
。 -
元组不可变:元组是不可变的,不能修改其中的元素。
#创建一个元组 my_tuple = (1,2,3,4,5) #访问元组元素 print(my_tuple[0])
集合(Set):无序且元素唯一的数据结构
-
添加元素:使用
add()
方法向集合中添加元素。 -
删除元素:使用
remove()
方法删除指定值的元素。 -
集合运算:支持并集、交集、差集等集合运算。
# 创建一个集合 my_set = {1, 2, 3, 4, 5} # 添加元素 my_set.add(6) print(my_set) # 输出: {1, 2, 3, 4, 5, 6} # 删除元素 my_set.remove(3) print(my_set) # 输出: {1, 2, 4, 5, 6} #并集 set1 = {1, 2, 3} set2 = {3, 4, 5} union_set = set1.union(set2) # 或者 union_set = set1 | set2 print(union_set) # 输出: {1, 2, 3, 4, 5} #交集 intersection_set = set1.intersection(set2) # 或者 intersection_set = set1 & set2 print(intersection_set) # 输出: {3} #差集 difference_set = set1.difference(set2) # 或者 difference_set = set1 - set2 print(difference_set) # 输出: {1, 2}
字典(Dictionary):
-
访问元素:通过键访问字典中的值,例如
my_dict['key']
。 -
添加键值对:使用
my_dict['new_key'] = value
添加新的键值对。 -
删除键值对:使用
del
关键字或pop()
方法删除指定键的键值对。 -
遍历字典:使用
for key, value in my_dict.items()
遍历字典的键值对。# 创建一个字典 my_dict = {'a': 1, 'b': 2, 'c': 3} # 访问字典元素 print(my_dict['a']) # 输出: 1 # 添加键值对 my_dict['d'] = 4 print(my_dict) # 输出: {'a': 1, 'b': 2, 'c': 3, 'd': 4} # 删除键值对 del my_dict['b'] print(my_dict) # 输出: {'a': 1, 'c': 3, 'd': 4} # 遍历字典 for key, value in my_dict.items(): print(key, value) # 输出: # a 1 # c 3 # d 4
数据库操作
- 读取数据
- 写入数据
读数据
步骤:连接数据库–>获取目标数据库最大表记录–>读取数据–>输出数据
#连接数据库
import pymysql
def get_conn(database_name,pwd):
# 连接数据库
con = pymysql.connect(
host='127.0.0.1', # 数据库所在地址URL
user='root', # 用户名
password='pwd', # 密码
database='database_name', # 目标数据库名称
port=3306, # 端口号
charset='utf8'
)
# 拿到查询游标
cur = con.cursor()
return con, cur
def get_max_id(cur):
#获取目标数据库最大表记录
sql = 'select MAX(ID) AS lastRecordId FROM 表名'
cur.execute(sql)
max_id = cur.fetchone()#返回的是元组
if max_id[0] == None:
return 1
return max_id[0]+1
def read_data(cur):
# 读取数据
sql = 'SELECT * FROM 表名'
cur.execute(sql)
data = cur.fetchall()
return data
#执行
if __name__ == '__main__':
con,cur = get_conn('test','123456')
max_id = get_max_id(cur)
print('Max ID:',max_id-1)
data = read_data(cur)
print('Data:',data)
cur.close()
con.close()
写(插入)数据(简单版)
步骤:连接数据库–>读取文件–>写入数据库
#连接数据库
import pymysql
def get_conn(database_name,pwd):
# 连接数据库
con = pymysql.connect(
host='127.0.0.1', # 数据库所在地址URL
user='root', # 用户名
password='pwd', # 密码
database='database_name', # 目标数据库名称
port=3306, # 端口号
charset='utf8'
)
# 拿到查询游标
cur = con.cursor()
return con, cur
def read_txt_file(file_path):
#读取.txt文件数据
with open(file_path, 'r', encoding='utf-8') as f:
data = f.readlines()
return data
def insert_data_into_db(data):
#从本地文件写入数据库
con,cur = get_con('test','123456')
for line in data:
fields = line.strip('\n').split(',')
print(fields)
# 假设目标数据库表为users,字段名为name、age、city
sql = f"INSERT INTO users (name, age, city) VALUES ('{fields[0]}', {fields[1]}, '{fields[2]}')"
cur.execute(sql)
con.commit()
cur.close()
con.close()
if __name__ == '__main__':
file_path = 'textTosql.txt'
data = read_text_file(file_path)
insert_data_into_db(data)
import os #批量读取文件
def get_file_path(path):
file_list = []#维护一个列表用于存储文件名
for file_name in os.listdir(path):
# 强迫症可以拼接完整的文件路径
file_path = os.path.join(path, file_name)#此步可以忽略
# 判断是否是文件
if os.path.isfile(file_path):
file_list.append(file_path)
#如何文件命名太乱,可以做一个筛选。
return file_list
#上面的get_file_path()是一个封装,后面要用就直接传入一个path调用
#eg:
filen_list = get_file_paths('D:\work_test\gs_data_analysis\data')
print(filen_list)
复杂版
想象一个场景,你需要批量将本地的数据写入数据库,文件肯定会在一个目录下,此时,你会怎么做?一个文件改一个file_path,然后一个一个运行插入?还是换一个思路??怎么能不傻瓜式的一个一个修改,做到一劳永逸?
复杂的地方在于:
- 文件数量增加
- 添加异常处理
它来了…
#前面连接数据库,插入的逻辑都是一样的,改变的是文件批量读取和增加异常处理
import pymysql,os
def get_con(dbname,pwd):
con =pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password=pwd,
db=dbname,
charset='utf8'
)
cur = con.cursor()
return con,cur
def read_all_show(path):
# 读取固定目录下的所有源文件
filename= os.listdir(path) #列出目录下的所有文件
filelist = [] #维护一个列表存储所有源文件
# 遍历文件列表
for file in filename:
# 使用 os.path.join 拼接目录路径文和件名,得到文件的完整路径
# file_path = os.path.join(path, file)
#可以添加判断语句,实现文件的筛选,利用文件名
if 'text'in file:
#例如:if '2024_1_17' in file:
#xxx
filelist.append(os.path.join(path, file))
data =[]
for file in filelist:
with open(file,'r',encoding='utf8') as f:
data.extend(f.readlines())
return data
# All_path = r'D:\work_test\gs_data_analysis\data'文件目录
def insert_into_db(data):
con,cur = get_con('test', '123456')
for line in data:
fields = line.strip('\n').split(',')
# print(fields)
if len(fields) >= 3:
try:
sql = "insert into users(name,age,city) values(%s,%s,%s)"
cur.execute(sql,(fields[0],fields[1],fields[2]))
con.commit()
print(f'{fields}新增数据成功')
except pymysql.err.IntegrityError as e:
print(f'{fields} 新增数据失败:{e}')
# pass
else:
print(f'数据格式错误:{fields}')
cur.close()
con.close()
if __name__ == '__main__':
data = read_all_show(r'D:\TextToSql')
insert_into_db(data)
今天的分享就到这里了,感兴趣的朋友可以跟我留言交流!