友情提示:将下文中代码拷贝到JupyterNotebook中直接执行即可,部分代码需要连续执行。
MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,一般中小型和大型网站的开发都选择 MySQL 作为网站数据库。
类型 | 大小 | 范围(有符号) | 范围(无符号) | 用途 |
---|---|---|---|---|
TINYINT | 1 字节 | (-128,127) | (0,255) | 小整数值 |
SMALLINT | 2 字节 | (-32 768,32 767) | (0,65 535) | 大整数值 |
MEDIUMINT | 3 字节 | (-8 388 608,8 388 607) | (0,16 777 215) | 大整数值 |
INT或INTEGER | 4 字节 | (-2 147 483 648,2 147 483 647) | (0,4 294 967 295) | 大整数值 |
BIGINT | 8 字节 | (-9,223,372,036,854,775,808,9 223 372 036 854 775 807) | (0,18 446 744 073 709 551 615) | 极大整数值 |
FLOAT | 4 字节 | (-3.402 823 466 E+38,-1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38) | 0,(1.175 494 351 E-38,3.402 823 466 E+38) | 单精度 浮点数值 |
DOUBLE | 8 字节 | (-1.797 693 134 862 315 7 E+308,-2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) | 0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) | 双精度 浮点数值 |
DECIMAL | 对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2 | 依赖于M和D的值 | 依赖于M和D的值 | 小数值 |
类型 | 大小 (字节) | 范围 | 格式 | 用途 |
---|---|---|---|---|
DATE | 3 | 1000-01-01/9999-12-31 | YYYY-MM-DD | 日期值 |
TIME | 3 | '-838:59:59'/'838:59:59' | HH:MM:SS | 时间值或持续时间 |
YEAR | 1 | 1901/2155 | YYYY | 年份值 |
DATETIME | 8 | 1000-01-01 00:00:00/9999-12-31 23:59:59 | YYYY-MM-DD HH:MM:SS | 混合日期和时间值 |
TIMESTAMP | 4 | 1970-01-01 00:00:00/2038 结束时间是第 2147483647 秒,北京时间 2038-1-19 11:14:07,格林尼治时间 2038年1月19日 凌晨 03:14:07 | YYYYMMDD HHMMSS | 混合日期和时间值,时间戳 |
字符串类型指CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET。下表描述了这些类型如何工作以及如何在查询中使用这些类型。
类型 | 大小 | 用途 |
---|---|---|
CHAR | 0-255字节 | 定长字符串 |
VARCHAR | 0-65535 字节 | 变长字符串 |
TINYBLOB | 0-255字节 | 不超过 255 个字符的二进制字符串 |
TINYTEXT | 0-255字节 | 短文本字符串 |
BLOB | 0-65 535字节 | 二进制形式的长文本数据 |
TEXT | 0-65 535字节 | 长文本数据 |
MEDIUMBLOB | 0-16 777 215字节 | 二进制形式的中等长度文本数据 |
MEDIUMTEXT | 0-16 777 215字节 | 中等长度文本数据 |
LONGBLOB | 0-4 294 967 295字节 | 二进制形式的极大文本数据 |
LONGTEXT | 0-4 294 967 295字节 | 极大文本数据 |
MySQL关键字 | 含义 |
NULL | 数据列可包含NULL值 |
NOT NULL | 数据列不允许包含NULL值 |
DEFAULT | 默认值 |
PRIMARY KEY | 主键 |
AUTO_INCREMENT | 自动递增,适用于整数类型 |
UNSIGNED | 无符号 |
CHARACTER SET name | 指定一个字符集 |
附建表sql如下:
CREATE DATABASE if not exists testdb;
USE testdb;
DROP TABLE IF EXISTS `t_book`;
CREATE TABLE `t_book` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`author` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`price` double(10, 2) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
INSERT INTO `t_book` VALUES (1, '红楼梦', '曹雪芹', 29.50);
INSERT INTO `t_book` VALUES (2, '西游记', '吴承恩', 15.80);
INSERT INTO `t_book` VALUES (3, '三国演义', '罗贯中', 30.00);
INSERT INTO `t_book` VALUES (4, '水浒传', '施耐庵', 26.58);
INSERT INTO `t_book` VALUES (5, '聊斋志异', '蒲松龄', 18.00);
INSERT INTO `t_book` VALUES (6, '镜花缘', '李汝珍', 15.50);
INSERT INTO `t_book` VALUES (7, '搜神记', '干宝', 22.00);
SET FOREIGN_KEY_CHECKS = 1;
在线安装命令:pip install pymysql
清华镜像安装:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pymysql
引入相关包:import pymysql
pymysql.connect()参数说明:
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pymysql
import pymysql
db = pymysql.connect(host="127.0.0.1",port=3306,user="root",password="lulu@123456!",database="testdb",charset="utf8")
接下来我们通过cursor()游标完成数据库取值
cur = db.cursor()# 建立游标对象
sql = "select * from t_book"# sql代码
cur.execute(sql)# 执行sql代码
data = cur.fetchall()# 获取结果集
data
((1, '红楼梦', '曹雪芹', 29.5),
(2, '西游记', '吴承恩', 15.8),
(3, '三国演义', '罗贯中', 30.0),
(4, '水浒传', '施耐庵', 26.58),
(5, '聊斋志异', '蒲松龄', 18.0),
(6, '镜花缘', '李汝珍', 15.5),
(7, '搜神记', '干宝', 22.0))
语法为:dataframe = pd.read_sql(sql,db)
import pymysql
import pandas as pd
db = pymysql.connect(host="127.0.0.1",port=3306,user="root",password="lulu@123456!",database="testdb",charset="utf8")
sql = "select * from t_book"
dataframe = pd.read_sql(sql,db)
dataframe.head(4)# 取前4行值
id | name | author | price | |
---|---|---|---|---|
0 | 1 | 红楼梦 | 曹雪芹 | 29.50 |
1 | 2 | 西游记 | 吴承恩 | 15.80 |
2 | 3 | 三国演义 | 罗贯中 | 30.00 |
3 | 4 | 水浒传 | 施耐庵 | 26.58 |
我们首先使用cursor.execute(“建库代码”)直接创建一个pytest数据库。
import pymysql
db=pymysql.connect(host="localhost",port=3306,user="root",password="lulu@123456!",charset="utf8")
cursor = db.cursor()
cursor.execute("create database if not exists pytest") # 创建数据库pytest
1
接下来我们在新建的pytest数据库中通过cursor.execute(“建表代码”)创建一张employee表,包含id、first_name、lastname、age、sex、income 6个字段。
import pymysql
db=pymysql.connect(host="localhost",port=3306,user="root",password="lulu@123456!",database="pytest",charset="utf8")
cursor = db.cursor()# 创建一张表employee 包含6个字段
cursor.execute("create table if not exists employee(id int primary key AUTO_INCREMENT,first_name char(20) not null,last_name char(20),age int,sex char(1),income float);")
0
因为涉及数据更改,所以需要使用db.commit():提交当前事务,或者当执行失败时使用db.rollback():回滚当前事务。如下例,我们插入两条数据:
import pymysql
db=pymysql.connect(host="localhost",port=3306,user="root",password="lulu@123456!",database="pytest",charset="utf8")
cursor = db.cursor()
sql = "insert into employee(first_name,last_name,age,sex,income) values('Taylor','Swift',33,'F',8000000.00),('Justin','Bieber',28,'M',7000000.00)"# 因为是AUTO_INCREMENT自增长字段,所以sql不需要指定id
try:
cursor.execute(sql)
db.commit()
except Exception as ex:
db.rollback()
print(repr(ex))
result = cursor.execute(sql)表示将执行成功条数返回给result,更新操作同样需要commit()或者rollback()。如下例,我们更新一条数据:
import pymysql
db=pymysql.connect(host="localhost",port=3306,user="root",password="lulu@123456!",database="pytest",charset="utf8")
cursor = db.cursor()
sql = "update employee set income = 11000000.00 where id = 1"
try:
result = cursor.execute(sql)# 返回执行成功条数
db.commit()
print("update {} success!".format(result))
except Exception as ex:
db.rollback()
print(repr(ex))
update 1 success!
result = cursor.execute(sql)表示将执行成功条数返回给result,删除操作同样需要commit()或者rollback()。如下例,我们删除两条数据:
import pymysql
db=pymysql.connect(host="localhost",port=3306,user="root",password="lulu@123456!",database="pytest",charset="utf8")
cursor = db.cursor()
sql = "delete from employee where id between {} and {} ".format(1,2)# 删除id在1到2之间的
try:
result = cursor.execute(sql)
db.commit()
print("delete {} success".format(result))
except Exception as ex:
db.rollback()
print(repr(ex))
delete 2 success
我们将testdb数据库中t_book的值全部取出,并通过for循环输出,如下例:
import pymysql
db=pymysql.connect(host="localhost",port=3306,user="root",password="lulu@123456!",database="testdb",charset="utf8")
cursor = db.cursor()
sql = "select * from t_book"
try:
cursor.execute(sql)
results = cursor.fetchall()
for row in results:
id=row[0]
name=row[1]
author=row[2]
price=row[3]
print("id={},name={},author={},price={}".format(id,name,author,price))
except Exception as ex:
print(repr(ex))
db.close()
id=1,name=红楼梦,author=曹雪芹,price=29.5
id=2,name=西游记,author=吴承恩,price=15.8
id=3,name=三国演义,author=罗贯中,price=30.0
id=4,name=水浒传,author=施耐庵,price=26.58
id=5,name=聊斋志异,author=蒲松龄,price=18.0
id=6,name=镜花缘,author=李汝珍,price=15.5
id=7,name=搜神记,author=干宝,price=22.0
利用Python Web Sever组件http.server(HTTPServer,BaseHTTPRequestHandler),打造静态及动态网页,实现API接口服务。
我们把返回的网页内容写入HtmlPage(Byte格式),go_GET表明当Web访问或者get请求时,返回HtmlPage。
服务启动后,网页访问路径 http://localhost:8081 或者 http://127.0.0.1:8081
from http.server import HTTPServer,BaseHTTPRequestHandler
import logging
logging.basicConfig(level=logging.INFO,encoding="utf-8", format='%(asctime)s - %(levelname)s- %(message)s')
class RequestHandle(BaseHTTPRequestHandler):
HtmlPage = b"""\
<html>
<head>
<meta charset="utf-8">
<title>Web Server</title>
</head>
<body>
hello Python Http!
</body>
</html>"""
def do_GET(self):
self.send_response(200) # 200 Status表明访问成功
self.send_header("Content-type","text/html")# 设置返回头部内容 格式text/html
self.send_header("Content-Length",str(len(self.HtmlPage)))
self.end_headers() # 发送HTTP头部结束
self.wfile.write(self.HtmlPage) # 返回静态网页 内容为Byte型
if __name__ == "__main__":
try:
server_address =("",8081) # 服务地址为本地端口8081
server = HTTPServer(server_address,RequestHandle)
logging.info("start server...127.0.0.1:8081") # 写入日志
server.serve_forever() # 持续开启服务和监听
except KeyboardInterrupt:
logging.info("^C received,shutting down the web servce") # 按下按键CTRL+C后,服务终止
server.socket.close() # 服务终止
#网页访问路径 http://localhost:8081 或者 http://127.0.0.1:8081
2022-06-27 13:18:38,218 - INFO- start server...127.0.0.1:8081
127.0.0.1 - - [27/Jun/2022 13:18:40] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [27/Jun/2022 13:18:40] "GET /favicon.ico HTTP/1.1" 200 -
2022-06-27 13:36:43,596 - INFO- ^C received,shutting down the web servce
我们定义一个json字典jsondict并将其转化为byte格式jsonbyte,go_POST表明是POST请求,利用self.wfile.write(self.jsonbyte)发送json数据,端口改为8082。
服务启动后,利用POSTMAN等工具发起POST请求 http://localhost:8082 或者 http://127.0.0.1:8082
from http.server import HTTPServer,BaseHTTPRequestHandler
import logging
import json
logging.basicConfig(level=logging.INFO,encoding="utf-8", format='%(asctime)s - %(levelname)s- %(message)s')
class RequestHandle(BaseHTTPRequestHandler):
jsondict = {"status":"ok","version":0,"data":{"name":"聊斋志异","author":"蒲松龄"}} # 定义一个json字符串
jsonbyte = bytes(str(jsondict),"utf-8")
def do_POST(self):
self.send_response(200) # 200 Status表明访问成功
self.send_header("Content-type","application/json;charset=UTF-8")# 设置返回头部内容 格式json
self.send_header("Content-Length",str(len(self.jsonbyte)))
self.end_headers() # 发送HTTP头部结束
self.wfile.write(self.jsonbyte) # 返回json格式数据
if __name__ == "__main__":
try:
server_address =("",8082) # 服务地址为本地端口8082
server = HTTPServer(server_address,RequestHandle)
logging.info("start server...127.0.0.1:8082") # 写入日志
server.serve_forever() # 持续开启服务和监听
except KeyboardInterrupt:
logging.info("^C received,shutting down the web servce") # 按下按键CTRL+C后,服务终止
server.socket.close() # 服务终止
#网页访问路径 http://localhost:8082 或者 http://127.0.0.1:8082
2022-06-27 14:20:26,031 - INFO- start server...127.0.0.1:8082
127.0.0.1 - - [27/Jun/2022 14:20:28] "POST / HTTP/1.1" 200 -
2022-06-27 14:34:26,006 - INFO- ^C received,shutting down the web servce
HTMLPage为动态网页模板,create_page函数将服务器当前信息传入模板,形成动态网页并转化为Byte格式。
send_page函数发送动态网页,do_GET表明当Web访问或者get请求时,分别调用create_page函数和send_page函数。
服务启动后,网页访问路径 http://localhost:8083 或者 http://127.0.0.1:8083
from http.server import HTTPServer,BaseHTTPRequestHandler
import logging
import time
logging.basicConfig(level=logging.INFO,encoding="utf-8",format='%(asctime)s - %(levelname)s- %(message)s')
port = 8083
class RequestHandle(BaseHTTPRequestHandler):
HTMLPage="""\
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>我的Web服务</title>
</head>
<body>
<table align="left" cellspacing="0" border="1" bgcolor="#F2F2F2" width="600px" >
<caption>服务器信息</caption>
<tr><td>标题</td><td>内容</td></tr>
<tr><td>时间</td><td>{data}</td></tr>
<tr><td>访问地址</td><td>{host}</td></tr>
<tr><td>访问端口</td><td>{port}</td></tr>
<tr><td>命令</td><td>{command}</td></tr>
<tr><td>地址</td><td>{path}</td></tr>
</table>
</body>
</html>
"""
def create_page(self): # 创建动态网页
value={"data":time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()),
"host":self.client_address[0],
"port":port,
"command":self.command,
"path":self.path}
HTMLPage = self.HTMLPage.format(**value) # 使用dict方式传入
BytePage = HTMLPage.encode("utf-8") # 转化为Byte格式
return BytePage
def send_page(self,page): # 发送动态网页
self.send_response(200) # 200 Status表明访问成功
self.send_header("Content-type","text/html") # 设置返回头部内容 格式text/html
self.send_header("Content-Length",str(len(page)))
self.end_headers()
self.wfile.write(page) # 返回动态网页 内容为Byte型
def do_GET(self):
page = self.create_page() # 创建需要返回的页面
self.send_page(page) # 返回状态及页面
if __name__ == "__main__":
#启动网页服务
try:
server_address= ("",port)# 服务地址为本地端口8083
server = HTTPServer(server_address,RequestHandle)
logging.info("动态网页服务启动...127.0.0.1:8083") # 写入日志
server.serve_forever() # 持续开启服务和监听
except KeyboardInterrupt:
logging.info("^C received,shutting down the web servce")# 按下按键CTRL+C后,服务终止
server.socket.close() # 服务终止
#网页访问路径 http://localhost:8083 或者 http://127.0.0.1:8083
2022-06-28 13:29:49,954 - INFO- 动态网页服务启动...127.0.0.1:8083
127.0.0.1 - - [28/Jun/2022 13:29:50] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [28/Jun/2022 13:29:50] "GET /favicon.ico HTTP/1.1" 200 -
errorpage为统一定义的错误网页动态模板,error_handle函数将调用该模板并将错误信息写入动态网页中。
正常情况下handle_file函数为读取文件服务,并将文件信息通过send_content函数返回到前端页面,如有报错,则执行error_handle函数。
服务启动后,网页访问路径 http://localhost:8084 或者 http://127.0.0.1:8084
from http.server import HTTPServer,BaseHTTPRequestHandler
import logging
logging.basicConfig(level=logging.INFO,encoding="utf-8",format='%(asctime)s - %(levelname)s- %(message)s')
port = 8084
class RequestHandle(BaseHTTPRequestHandler):
errorpage='''\
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>我的Web服务</title>
</head>
<body>
{}
</body>
</html>
'''
def handle_file(self,path): # 读取文件服务,传入文件地址
try:
with open(path,"rb") as file:
content = file.read()
self.send_content(content)
except IOError as ex: # 如有报错,调用error_handle函数,传入错误信息
content = "{} 错误:{}".format(path,repr(ex))# 提取错误信息
self.error_handle(content)# 调用统一错误网页动态模板
def send_content(self,content,status=200): # 发送动态网页
self.send_response(status) # 200 Status表明访问成功
self.send_header("Content-type","text/html")
self.send_header("Content-Length",str(len(content)))
self.end_headers()
self.wfile.write(content)# 返回动态网页 内容为Byte型
def error_handle(self,msg): # 统一输出错误接口
errorpage = self.errorpage.format(msg) # 将错误信息写入动态网页中
errorbytepage = errorpage.encode('utf-8') # 转码
self.send_content(errorbytepage) #调用发送接口
def do_GET(self):
self.handle_file("D://python.txt")
if __name__ == "__main__":
# 创建一个本地文件
pythonthis = """优美胜于丑陋
明了胜于晦涩
简洁胜于复杂
复杂胜于凌乱
扁平胜于嵌套
可读性很重要
"""
with open(file="D://python.txt",mode="wt") as file:
file.write(pythonthis)
#启动网页服务
try:
server_address= ("",port)# 服务地址为本地端口8084
server = HTTPServer(server_address,RequestHandle)
logging.info("动态网页服务启动...127.0.0.1:8084") # 写入日志
server.serve_forever() # 持续开启服务和监听
except KeyboardInterrupt:
logging.info("^C received,shutting down the web servce")# 按下按键CTRL+C后,服务终止
server.socket.close() # 服务终止
#网页访问路径 http://localhost:8084 或者 http://127.0.0.1:8084
2022-06-28 13:29:59,368 - INFO- 动态网页服务启动...127.0.0.1:8084
127.0.0.1 - - [28/Jun/2022 13:30:03] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [28/Jun/2022 13:30:03] "GET /favicon.ico HTTP/1.1" 200 -
服务启动后,网页访问路径 http://localhost:8085?id=4 或者 http://127.0.0.1:8085?id=4
self.path获取网址后缀值并将其返回到网页中,形成交互式网页服务。
from http.server import HTTPServer,BaseHTTPRequestHandler
import logging
logging.basicConfig(level=logging.INFO,encoding="utf-8",format='%(asctime)s - %(levelname)s- %(message)s')
port = 8085
class RequestHandle(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)#200 Status表明访问成功
self.send_header("Content-type","text/html")
self.end_headers()
self.wfile.write(bytes(self.path,'utf-8')) # 返回网址后缀
if __name__ == "__main__":
#启动网页服务
try:
server_address= ("",port)# 服务地址为本地端口8085
server = HTTPServer(server_address,RequestHandle)
logging.info("动态网页服务启动...127.0.0.1:8085") # 写入日志
server.serve_forever() # 持续开启服务和监听
except KeyboardInterrupt:
logging.info("^C received,shutting down the web servce")# 按下按键CTRL+C后,服务终止
server.socket.close() # 服务终止
#网页访问路径 http://localhost:8085?id=4 或者 http://127.0.0.1:8085?id=4
2022-06-28 13:21:44,906 - INFO- 动态网页服务启动...127.0.0.1:8085
127.0.0.1 - - [28/Jun/2022 13:21:48] "GET /?id=4 HTTP/1.1" 200 -
127.0.0.1 - - [28/Jun/2022 13:21:48] "GET /favicon.ico HTTP/1.1" 200 -