# PythonMySQL
**Repository Path**: FrankieAFei/PythonMySQL
## Basic Information
- **Project Name**: PythonMySQL
- **Description**: python的MySQL数据库操作类
- **Primary Language**: Python
- **License**: GPL-3.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 1
- **Created**: 2017-12-01
- **Last Updated**: 2024-06-30
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# pythonMySQL使用文档
---
## 写在前面
来源:将之前写的 [PHP操作MySQL类(2017.12.05版)][1] ,使用python重写。
依赖:开发时使用的python3.6(理论上只要python3.x都可以),需要mysql.connector模块(mysql-connector-python驱动)。
>mysql-connector-python驱动安装命令:
`pip install mysql-connector-python --allow-external mysql-connector-python`
如果上面的命令安装失败,可以试试另一个驱动:
`pip install mysql-connector`
## 更新注记
### 2017.12.05更新
- 将2017.12.05版的 [PHP操作MySQL类][1] 使用python重写而产生了这个东西
### 2018.01.05更新
- 考完试把文档补上
## 使用文档
注:由于 [PHP操作MySQL类][1] 是根据ThinkPHP3.2.3“模型”部分的语法来仿写的,可结合ThinkPHP3.2.3的文档参考使用。(别当真,红红火火恍恍惚惚)
### 1.初始化
首先填好配置文件config.py,然后在代码文件import pythonMySQL:
```
from pythonMySQL import *
```
配置文件初始化
```
# 默认使用数据库默认配置信息,索引为0
link = M('users') # users表示默认对users数据表进行操作
# 使用配置文件中其他配置信息,比如声明了"otherConfig"键的配置信息
link = M('users', 'otherConfig')
```
字典参数初始化
```
dbConfig = {
'host' : '127.0.0.1',
'port' : '3306',
'user' : 'root',
'password' : 'password', # 如无,程序会使用配置文件声明的数据库密码
'database' : 'db_name', # 必需
'charset' : 'utf8',
'autocommit' : True,
'DB_DEBUG' : True,
}
# 此处的1为配置代号,支持字符串代号,之后可直接使用配置代号切换数据表
link = M('users', 1, dbConfig)
```
**推荐使用配置文件的方法**,支持的配置信息:
```
"host" => '127.0.0.1', # 可选,服务器地址,默认127.0.0.1
"user" => 'root', # 可选,数据库用户名,默认root
'password' => 'pwd', # 必选,数据库密码
'database' => 'db_name', # 必选,数据库名
'port' => '3306', # 可选,端口号,默认3306
'dbms' => 'mysql', # 可选,数据库类型,默认mysql
'charset' => 'utf8', # 可选,数据库编码格式
'DB_DEBUG' => True, # 可选,是否开启DEBUG模式,请在系统上线后关闭DEBUG模式
'autocommit' => True # 可选,开启自动提交事务
```
### 2.支持的连贯操作
#### 1.WHERE
##### 1.字符串条件
使用字符串条件直接查询和操作,例如:
```
User = M("User") # 实例化User对象
User.where('type=1 AND status=1').select()
```
最后生成的SQL语句是
```
SELECT * FROM think_user WHERE type=1 AND status=1
```
使用字符串条件的时候,建议配合预处理机制,确保更加安全,例如:
```
Model.where("id=%d and username='%s' and xx='%f'", id, username, xx)).select()
Model.where("id=%d and username='%s' and xx='%f'", (id, username, xx)).select()
Model.where("id=%d and username='%s' and xx='%f'", [id, username, xx]).select()
```
##### 2.字典条件
推荐用法。
支持普通查询
```
User = M("User") # 实例化User对象
map = {}
map['name'] = 'thinkphp'
map['status'] = 1
# 把查询条件传入查询方法
User.where(map).select()
```
最后生成的SQL语句是
```
SELECT * FROM think_user WHERE `name`='thinkphp' AND status=1
```
支持[表达式查询](#expression)
```
map['字段1'] = ('表达式', '查询条件1', '逻辑符,可为空字符串,默认AND,或OR和XOR', 'e')
map['字段2'] = ('表达式', '查询条件2', '逻辑符,可为空字符串,默认AND,或OR和XOR', 'e')
Model.where(map).select()
```
支持多次调用。
#### 2.TABLE
除了数据表前缀,支持ThinkPHP支持的所有table用法。
**建议:在CURD链式调用放于首位。**
#### 3.ALIAS
支持ThinkPHP支持的所有alias用法。
#### 4.FIELD
用于查询
```
Model.field('id,title,content').select()
```
可以给某个字段设置别名,例如:
```
Model.field('id,nickname as name').select()
```
使用SQL函数
```
Model.field('id,SUM(score)').select()
```
使用字典参数,可以为某些字段定义别名
```
Model.field({'id':'','nickname':'name'}).select()
```
对于一些更复杂的字段要求,字典的优势则更加明显,例如:
```
Model.field({'id':'','concat(name,"-",id)':'truename','LEFT(title,7)':'sub_title'}).select()
```
执行的SQL相当于:
```
SELECT id,concat(name,"-",id) as truename,LEFT(title,7) as sub_title FROM table
```
支持获取所有字段和过滤字段(详见ThinkPHP3.2.3文档)。
#### 5.ORDER
用法与ThinkPHP相同
#### 6.LIMIT
用法与ThinkPHP相同
#### 7.PAGE
只支持两个数字参数的写法:
```
page(2,10) # 表示单页量为10,取第二页,即取出符合条件的第11-20条数据
```
#### 8.GROUP
用法与ThinkPHP相同
#### 9.HAVING
用法与ThinkPHP相同
#### 10.JOIN
(跟ThinkPHP有较大区别)
只传一个字符串,默认INNER JOIN
```
M('t1').join('t2 on t1.id=t2.id').select()
# 相当于select * from t1 INNER JOIN t2 on t1.id=t2.id
```
传数组(list或tuple)
(前两个元素必须是字符串,第二个元素须是"INNER","LEFT","RIGHT","FULL"之一)
```
M('t1').join(('t2 on t1.id=t2.id', 'LEFT')).select()
# 相当于select * from t1 LEFT JOIN t2 on t1.id=t2.id
```
支持多次调用。
>注:MySQL其实不支持FULL JOIN,建议用 left join + union(可去除重复数据)+ right join 作为替代方案。
#### 11.fetchSql
用法与ThinkPHP相同
### 3.支持的CURD操作(增删查改)
以下操作失败都返回False,可调用成员函数`showError()`打印SQL错误信息。
#### 1.数据读取
##### find()
读取数据(仅一条)
```
data = User.where('status=1 AND name="thinkphp"').find()
```
查询成功返回字典,如果无数据返回None
##### select()
读取数据集
```
list = User.where('status=1').order('create_time').limit(10).select()
```
查询成功返回由字典组成的列表,如果无数据返回空列表
#### 2.数据插入
##### add()
传入字典
```
User = M("User") # 实例化User对象
data = {}
data['name'] = 'ThinkPHP'
data['email'] = 'ThinkPHP@gmail.com'
User.add(data)
```
插入成功返回插入数据的自增ID(如果无自增ID将返回0)
##### addAll()
批量写入(须传入由字典组成的列表或元组)
```
dataList = [
{'name':'thinkphp','email':'thinkphp@gamil.com'},
{'name':'onethink','email':'onethink@gamil.com'}
]
User.addAll(dataList)
```
插入成功返回其中第一条插入数据的自增ID(如果无自增ID将返回0)
注:如果插入的数据都指定了自增ID,将返回最后一条数据的自增ID
#### 3.数据更新
返回值都是影响的记录数(如果更新前的数据和更新后的没有变化,则返回0)
##### save()
```
User = M("User") # 实例化User对象
data = {}
# 要修改的数据对象属性赋值
data['name'] = 'ThinkPHP'
data['email'] = 'ThinkPHP@gmail.com'
User.where('id=5').save(data) # 根据条件更新记录
```
为了保证数据库的安全,避免出错更新整个数据表,如果没有任何更新条件,数据对象本身也不包含主键字段的话,save方法不会更新任何数据库的记录。
除非使用下面的方式:
```
User = M("User") # 实例化User对象
data = {}
# 要修改的数据对象属性赋值
data['id'] = 5
data['name'] = 'ThinkPHP'
data['email'] = 'ThinkPHP@gmail.com'
User.save(data) # 根据条件保存修改的数据
```
如果id是数据表的主键的话,系统自动会把主键的值作为更新条件来更新其他字段的值
##### setField()
如果只是更新个别字段的值,可以使用setField 方法:
```
User = M("User") # 实例化User对象
# 更改用户的name值
User.where('id=5').setField('name','ThinkPHP')
```
setField方法支持同时更新多个字段,只需要传入字典即可(这将与save相同)
```
User = M("User") # 实例化User对象
# 更改用户的name和email的值
data = {'name':'ThinkPHP','email':'ThinkPHP@gmail.com'}
User.where('id=5').setField(data)
```
而对于统计字段(通常指的是数字类型)的更新,还提供了setInc 和setDec 方法。
```
User = M("User") # 实例化User对象
User.where('id=5').setInc('score',3) # 用户的积分加3
User.where('id=5').setInc('score') # 用户的积分加1
User.where('id=5').setDec('score',5) # 用户的积分减5
User.where('id=5').setDec('score') # 用户的积分减1
```
不支持延迟更新。
#### 4.数据删除
返回是删除的记录数
不支持传入主键删除数据(与ThinkPHP有区别)
普通用法:
```
User.where('status=0').delete() # 删除所有状态为0的用户数据
```
高级用法,delete与join的结合使用:
```
User=M('t1')
User.join('t2 on t2.id = t1.id').delete('t1')
# DELETE t1 FROM `t1` INNER JOIN t2 on t2.id = t1.id
# 表示删除t1表中id与t2的id相同的数据
# delete方法中的参数用于指定删除哪个表中符合条件的数据
```
### 4.查询语言
与ThinkPHP最大的不同在于使用了"s""m""e"关键词:
>**"s"**:进行单条件对应查询,示例:
`map['status&title'] =('1','thinkphp')`或者`map['status&title'] =('1','thinkphp','','s')`
即`status=1 AND title='thinkphp'`
**"m"**:单字段进行多条件查询,示例:
`map['name'] = ('ThinkPHP',('like','%a%','','e'),'or','m')`
即`name='ThinkPHP' OR name LIKE '%a%'`
其中"m"和"e"关键词主要是为了与表达式查询做区分。
>举个例子:
`map['name'] = ('ThinkPHP','is null')`和`map['name'] = ('exp','is null')`
后者本来是表达式查询,但是还可以被辨别为`name='exp' AND name='is null'`;
所以干脆给前者加个`"m"`表示非表达式查询,解析为`name='ThinkPHP' AND name='is null'`。
后者没有"m"关键词,解析为`name is null`。
#### 1.查询方法
支持字符串查询和字典查询。
以及**推荐使用字典查询**,因为where查询直接传字符串不做任何检查(不安全所以不支持)