Python零基础速成班-第18讲-Python for Database MySQL数据库,Web Sever打造网页和API接口服务

Python零基础速成班-第18讲-Python for Database MySQL数据库,Web Sever打造网页和API接口服务

学习目标

  1. Python Database MySQL数据库
  2. Python Web Sever打造网页和API接口服务

友情提示:将下文中代码拷贝到JupyterNotebook中直接执行即可,部分代码需要连续执行。

1、Python Database MySQL数据库

1.1 MySQL数据库简介

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,一般中小型和大型网站的开发都选择 MySQL 作为网站数据库。

1.2 MySQL数据库数据类型简介

1.2.1 数值类型
  1. MySQL支持所有标准SQL数值数据类型。
  2. 这些类型包括严格数值数据类型(INTEGER、SMALLINT、DECIMAL和NUMERIC),以及近似数值数据类型(FLOAT、REAL和DOUBLE PRECISION)。
  3. 关键字INT是INTEGER的同义词,关键字DEC是DECIMAL的同义词。
  4. BIT数据类型保存位字段值,并且支持MyISAM、MEMORY、InnoDB和BDB表。
  5. 作为SQL标准的扩展,MySQL也支持整数类型TINYINT、MEDIUMINT和BIGINT。下面的表显示了需要的每个整数类型的存储和范围。
类型大小范围(有符号)范围(无符号)用途
TINYINT1 字节(-128,127)(0,255)小整数值
SMALLINT2 字节(-32 768,32 767)(0,65 535)大整数值
MEDIUMINT3 字节(-8 388 608,8 388 607)(0,16 777 215)大整数值
INT或INTEGER4 字节(-2 147 483 648,2 147 483 647)(0,4 294 967 295)大整数值
BIGINT8 字节(-9,223,372,036,854,775,808,9 223 372 036 854 775 807)(0,18 446 744 073 709 551 615)极大整数值
FLOAT4 字节(-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)单精度
浮点数值
DOUBLE8 字节(-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的值小数值
1.2.2 日期和时间类型
  1. 表示时间值的日期和时间类型为DATETIME、DATE、TIMESTAMP、TIME和YEAR。
  2. 每个时间类型有一个有效值范围和一个"零"值,当指定不合法的MySQL不能表示的值时使用"零"值。
类型大小
(字节)
范围格式用途
DATE31000-01-01/9999-12-31YYYY-MM-DD日期值
TIME3'-838:59:59'/'838:59:59'HH:MM:SS时间值或持续时间
YEAR11901/2155YYYY年份值
DATETIME81000-01-01 00:00:00/9999-12-31 23:59:59YYYY-MM-DD HH:MM:SS混合日期和时间值
TIMESTAMP4

1970-01-01 00:00:00/2038

结束时间是第 2147483647 秒,北京时间 2038-1-19 11:14:07,格林尼治时间 2038年1月19日 凌晨 03:14:07

YYYYMMDD HHMMSS混合日期和时间值,时间戳
1.2.3 字符串类型

字符串类型指CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET。下表描述了这些类型如何工作以及如何在查询中使用这些类型。

类型大小用途
CHAR0-255字节定长字符串
VARCHAR0-65535 字节变长字符串
TINYBLOB0-255字节不超过 255 个字符的二进制字符串
TINYTEXT0-255字节短文本字符串
BLOB0-65 535字节二进制形式的长文本数据
TEXT0-65 535字节长文本数据
MEDIUMBLOB0-16 777 215字节二进制形式的中等长度文本数据
MEDIUMTEXT0-16 777 215字节中等长度文本数据
LONGBLOB0-4 294 967 295字节二进制形式的极大文本数据
LONGTEXT0-4 294 967 295字节极大文本数据
1.2.4 数据类型的属性
MySQL关键字含义
NULL数据列可包含NULL值
NOT NULL数据列不允许包含NULL值
DEFAULT默认值
PRIMARY KEY主键
AUTO_INCREMENT自动递增,适用于整数类型
UNSIGNED无符号
CHARACTER SET name指定一个字符集

1.3 MySQL数据库安装配置及数据准备

  1. 我们选择开源的MySQL8.0+版本,安装在本地运行。具体教程请参考
    Mysql8.0.22安装与配置详细教程
  2. 安装好后,我们创建一个testdb数据库,新建t_book表,并插入6条数据,如下图:

18-1

  1. MySQL连接信息:数据库账号"root",密码"lulu@123456!“,端口"3306”,数据库名"testdb",编码"utf8"

附建表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;

1.4 Python连接MySQL数据库并取值(select)

在线安装命令:pip install pymysql
清华镜像安装:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pymysql
引入相关包:import pymysql

接下来我们通过db = pymysql.connect()创建数据库连接

pymysql.connect()参数说明:

  • host(str):MySQL服务器地址
  • port(int):MySQL服务器端口号
  • user(str):用户名
  • passwd(str):密码
  • database(str):数据库名称
  • charset(str):连接编码
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")
db 是数据库连接对象,其支持的方法有:
  • cursor():使用该连接创建并返回游标
  • commit():提交当前事务
  • rollback():回滚当前事务
  • close():关闭连接

接下来我们通过cursor()游标完成数据库取值

cursor() 游标支持的方法有:
  • execute(op):执行一个数据库的查询命令
  • fetchone():取得结果集的下一行
  • fetchmany(size):获取结果集的下几行
  • fetchall(): 获取结果集中的所有行
  • rowcount():返回数据条数或影响行数
  • close():关闭游标对象
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))
我们还可以使用Pandas 连接数据库并取值,结果直接转化为DataFrame 格式。

语法为: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行值
idnameauthorprice
01红楼梦曹雪芹29.50
12西游记吴承恩15.80
23三国演义罗贯中30.00
34水浒传施耐庵26.58

1.5 Python创建MySQL数据库和表(create)

我们首先使用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个字段。

18-2

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

1.6 Python向MySQL表中插入数据(insert)

因为涉及数据更改,所以需要使用db.commit():提交当前事务,或者当执行失败时使用db.rollback():回滚当前事务。如下例,我们插入两条数据:

18-3

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))

1.7 Python更新MySQL表中数据(update)

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!

1.8 Python删除MySQL表中数据(delete)

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

1.9 通过循环方式取值(select)

我们将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

2、Python Web Sever打造网页和API接口服务

2.1 目标及代码功能简介:

2.1.1 目标

利用Python Web Sever组件http.server(HTTPServer,BaseHTTPRequestHandler),打造静态及动态网页,实现API接口服务。

2.1.2 代码功能介绍

1 BaseHTTPRequestHandler:这是一个以TCPServer为基础开发的模块,可以在请求外层添加http协议报文,发送http协议,常用方法及属性如下:(BaseHTTPRequestHandler简写为handler)
  1. handler.path 包含的请求路径和GET请求的数据
  2. handler.command 请求类型GET、POST、PUT…
  3. handler.headers 请求的头
  4. handler.responses HTTP错误代码及对应错误信息的字典
  5. handler.handle() 用于处理某一连接对象的请求,调用handle_one_request方法处理
  6. handler.handle_one_request() 根据请求类型调用do_XXX()方法,XXX为请求类型
  7. handler.do_XXX() 处理请求
  8. handler.send_error() 发送并记录一个完整的错误回复到客户端,内部调用send_response()方法实现
  9. handler.send_response() 发送一个响应头并记录已接收的请求
  10. handler.send_header() 发送一个指定的HTTP头到输出流。 keyword 应该指定头关键字,value 指定它的值
  11. handler.end_headers() 发送一个空白行,标识发送HTTP头部结束
  12. handler.wfile self.connection.makefile(“rb”, self.wbufsize) self.wbufsize = -1 应答的HTTP文本流对象,可写入应答信息
  13. handler.rfile self.connection.makefile(‘wb’, self.rbufsize) self.rbufsize = 0 请求的HTTP文本流对象,可读取请求信息
2 Http Server:用于网页及接口的监听和应答。基于BaseHTTPServer 的Http Server的处理流程如下:
  1. HTTPServer绑定对应的应答类 http_server = HTTPServer((’’, int(port)), ServerHTTP)。
  2. 监听端口 http_server.serve_forever(),使用select.select()循环监听请求,当接收到请求后调用当监听到请求时,取出请求对象。
  3. 应答类 ServerHTTP(),创建新线程处理请求对象,使用ServerHTTP.do_XXX方法。

2.2 完成一个静态网页服务,如下例:

我们把返回的网页内容写入HtmlPage(Byte格式),go_GET表明当Web访问或者get请求时,返回HtmlPage。
服务启动后,网页访问路径 http://localhost:8081 或者 http://127.0.0.1:8081

18-4

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

2.3完成一个API接口服务端,返回JSON数据,如下例:

我们定义一个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

18-5

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

2.4 完成一个动态网页服务,如下例:

HTMLPage为动态网页模板,create_page函数将服务器当前信息传入模板,形成动态网页并转化为Byte格式。
send_page函数发送动态网页,do_GET表明当Web访问或者get请求时,分别调用create_page函数和send_page函数。
服务启动后,网页访问路径 http://localhost:8083 或者 http://127.0.0.1:8083

18-6

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 -

2.5 完成一个动态网页服务,读取服务器文件返回到网页中,如下例:

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 -

2.6 完成一个动态交互式网页服务,获取网址后缀值,返回在网页中,如下例:

服务启动后,网页访问路径 http://localhost:8085?id=4 或者 http://127.0.0.1:8085?id=4
self.path获取网址后缀值并将其返回到网页中,形成交互式网页服务。

18-7

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 -
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我会根据您的问题来为您解答SQL Server的基础学习中,如何创建登录用户、创建数据库用户以及分配权限的问题。 1. 创建登录用户 在SQL Server中创建登录用户需要使用以下语句: ``` CREATE LOGIN login_name WITH PASSWORD = 'password'; ``` 其中,`login_name`是您要创建的登录用户名,`password`是该用户的密码。 如果需要为该用户指定特定的数据库作为默认数据库,可以使用以下语句: ``` CREATE LOGIN login_name WITH PASSWORD = 'password', DEFAULT_DATABASE = database_name; ``` 其中,`database_name`是您要指定的数据库名称。 2. 创建数据库用户 在SQL Server中创建数据库用户需要使用以下语句: ``` USE database_name; CREATE USER user_name FOR LOGIN login_name; ``` 其中,`database_name`是您要创建用户的数据库名称,`user_name`是您要创建的数据库用户名,`login_name`是您刚刚创建的登录用户名。 如果需要为该用户指定特定的模式作为默认模式,可以使用以下语句: ``` USE database_name; CREATE USER user_name FOR LOGIN login_name WITH DEFAULT_SCHEMA = schema_name; ``` 其中,`schema_name`是您要指定的模式名称。 3. 分配权限 在SQL Server中分配权限需要使用以下语句: ``` USE database_name; GRANT permission_name TO user_name; ``` 其中,`database_name`是要分配权限的数据库名称,`permission_name`是要授予的权限名称,`user_name`是要授予权限的数据库用户名。 如果需要撤销该用户的权限,可以使用以下语句: ``` USE database_name; REVOKE permission_name FROM user_name; ``` 以上就是SQL Server中创建登录用户、创建数据库用户以及分配权限的基本操作方法。希望这些信息对您有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值