├── demo.py ├── README.md └── mysql_client_tools.py /demo.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import random 3 | from datetime import datetime 4 | from mysql_client_tools import MySQLClient 5 | 6 | # 初始化连接 7 | connector = MySQLClient( 8 | host='localhost', 9 | port=3306, 10 | user='root', 11 | password='password', 12 | database='test' 13 | ) 14 | 15 | # 插入单行数据 16 | data = {'name': 'Alice', 'age': 20, 'created_at': datetime.now()} 17 | connector.insert('users', data) 18 | 19 | # 插入多行数据 20 | data_list = [{'name': 'Bob', 'age': 25, 'created_at': datetime.now()}, 21 | {'name': 'Charlie', 'age': 30, 'created_at': datetime.now()}] 22 | connector.insert_many('users', data_list) 23 | 24 | # 查询数据 25 | result = connector.execute("SELECT * FROM users") 26 | print(result) 27 | 28 | # 查询单条数据 29 | result = connector.query_one("SELECT * FROM users WHERE name = %s", ('Alice',)) 30 | print(result) 31 | 32 | # 查询多条数据 33 | result = connector.execute("SELECT * FROM users WHERE age > %s", (25,)) 34 | print(result) 35 | 36 | # 更新数据 37 | data = {'age': random.randint(20, 40)} 38 | where_clause = "name = %s" 39 | connector.update('users', data, where_clause) 40 | 41 | # 删除数据 42 | where_clause = "age < %s" 43 | connector.delete('users', where_clause) 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mysql-client-tools 2 | ## 说明 3 | 以下是使用Python连接MySQL数据库的代码和使用方法,代码支持查询、插入、更新和删除操作,使用了连接池提高了性能和可靠性。 4 | 5 | ## 准备工作 6 | 7 | 在使用代码之前,需要先安装好`pymysql`和`DBUtils`模块。可以使用以下命令进行安装: 8 | 9 | ``` 10 | pip install pymysql 11 | pip install dbutils 12 | ``` 13 | 14 | ## 使用方法 15 | 16 | ### 连接数据库 17 | 18 | 首先需要创建一个`MySQLConnector`对象,用于连接数据库。构造函数需要传入MySQL服务器的连接信息,包括主机名、端口号、用户名、密码、数据库名等参数。其中`max_connections`参数表示连接池中最大连接数,默认为5。 19 | 20 | ``` 21 | from mysql_connector import MySQLConnector 22 | 23 | conn = MySQLConnector(host='localhost', port=3306, user='root', password='password', database='mydb', max_connections=10) 24 | ``` 25 | 26 | ### 查询数据 27 | 28 | 查询数据可以使用`execute`方法,该方法接收一个SQL语句和可选的参数列表作为参数,返回一个包含查询结果的字典列表。如果查询结果为空,则返回一个空列表。查询中如果有`datetime`类型的字段,会自动转换为字符串类型输出。 29 | 30 | ``` 31 | result = conn.execute("SELECT * FROM mytable") 32 | print(result) 33 | ``` 34 | 35 | ### 插入数据 36 | 37 | 插入单行数据可以使用`insert`方法,该方法接收两个参数,分别为表名和一个包含数据的字典,其中字典的键为字段名,值为要插入的数据。插入多行数据可以使用`insert_many`方法,该方法接收两个参数,分别为表名和一个包含多个数据字典的列表,列表中的每个字典表示一行要插入的数据。 38 | 39 | ``` 40 | data = {'name': 'Alice', 'age': 20, 'created_at': datetime.now()} 41 | conn.insert('mytable', data) 42 | 43 | data_list = [ 44 | {'name': 'Bob', 'age': 25, 'created_at': datetime.now()}, 45 | {'name': 'Charlie', 'age': 30, 'created_at': datetime.now()} 46 | ] 47 | conn.insert_many('mytable', data_list) 48 | ``` 49 | 50 | ### 更新数据 51 | 52 | 更新数据可以使用`update`方法,该方法接收三个参数,分别为表名、一个包含要更新的数据的字典和一个表示更新条件的字符串,更新条件的格式为SQL中`WHERE`子句的格式。 53 | 54 | ``` 55 | data = {'age': 21} 56 | conn.update('mytable', data, 'name="Alice"') 57 | ``` 58 | 59 | ### 删除数据 60 | 61 | 删除数据可以使用`delete`方法,该方法接收两个参数,分别为表名和一个表示删除条件的字符串,删除条件的格式为SQL中`WHERE`子句的格式。 62 | 63 | ``` 64 | conn.delete('mytable', 'age=25') 65 | ``` 66 | -------------------------------------------------------------------------------- /mysql_client_tools.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import pymysql 3 | from datetime import datetime 4 | from pymysql import OperationalError 5 | from dbutils.pooled_db import PooledDB 6 | 7 | class MySQLClient: 8 | def __init__(self, host, port, user, password, database, charset='utf8mb4', max_connections=5): 9 | try: 10 | self.pool = PooledDB( 11 | creator=pymysql, 12 | host=host, 13 | port=port, 14 | user=user, 15 | password=password, 16 | database=database, 17 | charset=charset, 18 | autocommit=False, 19 | maxconnections=max_connections, 20 | cursorclass=pymysql.cursors.DictCursor 21 | ) 22 | except OperationalError as e: 23 | print(f"Cannot connect to database: {e}") 24 | exit(1) 25 | 26 | @staticmethod 27 | def __dict_datetime_obj_to_str(result_dict): 28 | """把字典里面的datetime对象转成字符串""" 29 | if result_dict: 30 | result_replace = {k: v.__str__() for k, v in result_dict.items() if isinstance(v, datetime)} 31 | result_dict.update(result_replace) 32 | return result_dict 33 | 34 | def execute(self, sql, params=None): 35 | """ 36 | 执行,返回的为 list,可单条也可多条 37 | """ 38 | conn = self.pool.connection() 39 | cursor = conn.cursor() 40 | self.cursor = cursor 41 | 42 | try: 43 | if params is None: 44 | cursor.execute(sql) 45 | else: 46 | cursor.execute(sql, params) 47 | return [self.__dict_datetime_obj_to_str(row_dict) for row_dict in cursor.fetchall()] 48 | except Exception as e: 49 | print(f"Cannot execute query all: {e}") 50 | return None 51 | finally: 52 | cursor.close() 53 | conn.close() 54 | 55 | def executemany(self, sql, params): 56 | """ 57 | 插入和更新时使用 58 | """ 59 | conn = self.pool.connection() 60 | cursor = conn.cursor() 61 | self.cursor = cursor 62 | 63 | try: 64 | cursor.executemany(sql, params) 65 | conn.commit() 66 | except Exception as e: 67 | conn.rollback() 68 | print(f"Cannot execute query: {e}") 69 | return None 70 | finally: 71 | cursor.close() 72 | conn.close() 73 | 74 | def query_one(self, sql, params=None): 75 | """ 76 | 查询单条数据,返回的为dict 77 | """ 78 | conn = self.pool.connection() 79 | cursor = conn.cursor() 80 | self.cursor = cursor 81 | 82 | try: 83 | if params is None: 84 | cursor.execute(sql) 85 | else: 86 | cursor.execute(sql, params) 87 | result = cursor.fetchone() 88 | return self.__dict_datetime_obj_to_str(result) 89 | except Exception as e: 90 | print(f"Cannot execute query one: {e}") 91 | return None 92 | finally: 93 | cursor.close() 94 | conn.close() 95 | 96 | def insert(self, table, data): 97 | """ 98 | 插入单条数据 99 | """ 100 | columns = ", ".join(data.keys()) 101 | values_template = ", ".join(["%s"] * len(data)) 102 | sql = f"INSERT INTO {table} ({columns}) VALUES ({values_template})" 103 | params = tuple(data.values()) 104 | self.executemany(sql, [params]) 105 | 106 | def insert_many(self, table, data_list): 107 | """ 108 | 批量插入数据 109 | """ 110 | columns = ", ".join(data_list[0].keys()) 111 | values_template = ", ".join(["%s"] * len(data_list[0])) 112 | sql = f"INSERT INTO {table} ({columns}) VALUES ({values_template})" 113 | params_list = [tuple(data.values()) for data in data_list] 114 | self.executemany(sql, params_list) 115 | 116 | def update(self, table, data, where_clause): 117 | """ 118 | 更新数据 119 | """ 120 | set_clause = ", ".join([f"{key}=%s" for key in data.keys()]) 121 | sql = f"UPDATE {table} SET {set_clause} WHERE {where_clause}" 122 | params = tuple(data.values()) 123 | self.executemany(sql, [params]) 124 | 125 | def delete(self, table, where_clause): 126 | """ 127 | 删除数据 128 | """ 129 | sql = f"DELETE FROM {table} WHERE {where_clause}" 130 | self.execute(sql) 131 | --------------------------------------------------------------------------------