Flask-03

SQLAlchemy

SQLAlchemy是一个数据库的ORM框架,让我们操作数据库的时候不要再用SQL语句了,跟直接操作模型一样。安装命令为:pip install SQLAlchemy。

通过SQLAlchemy连接数据库

1.SQLAlchemy是一个独立的ORM框架,可以独立于FLask存在,也可以再其他项目使用
2.Flask-SQLAlchemy:对SQLAlchemy的一个封装,能够更适合在Flask中使用

#coding=utf-8
from flask import Flask,render_template
from sqlalchemy import create_engine
from flask_sqlalchemy import SQLAlchemy

app=Flask(__name__)

# 数据库的配置变量

# 数据库的配置变量
HOSTNAME = '127.0.0.1'
PORT     = '3306'
DATABASE = 'ppl_flask01'
USERNAME = 'root'
PASSWORD = 
DB_URI = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(USERNAME,PASSWORD,HOSTNAME,PORT,DATABASE)
app.config['SQLALCHEMY_DATABASE_URI']=DB_URI#配置数据库的连接

# 创建数据库引擎
db=SQLAlchemy(app)


@app.route('/')
def index():
    #测试代码测试是否连接成果

    engine=db.get_engine()
    # 创建连接
    with engine.connect() as conn:
        result = conn.execute('SELECT 1')
        print(result.fetchone())

    return "hello"

if __name__=='__main__':
    app.run(debug=True)

在这里插入图片描述

后期补上的利用ORM与Mysql进行数据交互

db.create_all()没有解决,但是可以利用pymysql在数据库中新建表,连接表后进行增删查改

在表中添加数据

#coding=utf-8
from flask import Flask,render_template
from flask_sqlalchemy import SQLAlchemy
import mysql.connector

app=Flask(__name__)

# 数据库的配置变量
HOSTNAME = '127.0.0.1'
PORT     = '3306'
DATABASE = 'ppl_flask01'
USERNAME = 'root'
PASSWORD = 
DB_URI = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(USERNAME,PASSWORD,HOSTNAME,PORT,DATABASE)
app.config['SQLALCHEMY_DATABASE_URI']=DB_URI
app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=True
db=SQLAlchemy(app)

# 创建数据库引擎


@app.route('/article')
def article_view():
    #1.添加数据
    # article=Article(title="感叹",content="xxxxx")
    # db.session.add(article)
    # #做一个提交操作
    # db.session.commit()

    # 2.查询数据
    #filter_by:返回一个类列表对象
    # article=Article.query.filter_by(id=1)[0]
    # print(article.title)

    #3.修改数据
    # article=Article.query.filter_by(id=4)[0]
    # article.content="yyy"
    # db.session.commit()


    #删除数据
    article=Article.query.filter_by(id=4).delete()
    db.session.commit()
    return "操作成功"


#定义ORM模型
class Article(db.Model):
    __tablename__='article'
    id =db.Column(db.Integer,primary_key=True,autoincrement=True)
    title=db.Column(db.String(200),nullable=False)
    content=db.Column(db.Text,nullable=False)


@app.route('/')
def hello_world():
    #写一个测试代码来验证是否连接成功
    engine=db.get_engine()
    with engine.connect() as conn:
        result =conn.execute("select 1")
        print(result.fetchone())
    return 'Hello World!'


if __name__=='__main__':
    app.run(debug=True)
    db.create_all()

在这里插入图片描述

python在MySQL新建表

以下操作的前提代码均有:

import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="root",
  passwd=,
  database = "zl_flask",
)

mycursor = mydb.cursor()

db.create.all()无法解决,所以直接用mysql.connector

import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="root",
  passwd=,
  database = "ppl_flask01",
)

mycursor = mydb.cursor()

mycursor.execute("CREATE TABLE customers (name VARCHAR(255), address VARCHAR(255))")

在这里插入图片描述

python在MySQL增删改查

插入表

要把记录插入到MySQL中的表中,使用“INSERT INTO”语句。

#coding=utf-8
import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="root",
  passwd=,
  database = "ppl_flask01",
)

mycursor=mydb.cursor()

sql = "INSERT INTO book (name, address) VALUES (%s, %s)"
val = ("红楼梦", "Highway 21")
mycursor.execute(sql, val)
mydb.commit()

print(mycursor.rowcount, "条记录已插入")

在这里插入图片描述

插入多行

要将多行插入到表中,使用executemany()方法。
executemany()方法的第二个参数是一个元组列表,包含了要插入的数据:

#coding=utf-8
import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="root",
  passwd=,
  database = "ppl_flask01",
)

mycursor=mydb.cursor()
# mycursor.execute("CREATE TABLE book (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255), address VARCHAR(255))")
sql = "INSERT INTO book (name, address) VALUES (%s, %s)"
val = [
  ('三国演义', 'Lowstreet 4'),
  ('西游记', 'Apple st 652'),
  ('水浒传', 'Mountain 21'),
  ('云间有个小卖部', 'Valley 345'),
  ('你听我说', 'Ocean blvd 2'),
  ('落霞', 'Green Grass 1'),

]
mycursor.executemany(sql, val)
mydb.commit()
print(mycursor.rowcount, "条记录已插入")

在这里插入图片描述

从表中选取(SELECT)数据

从MySQL表中选取(SELECT)数据

使用“SELECT”语句:

注意: 使用了fetchall()方法,它从最后所执行语句的结果中,获取所有行。

#coding=utf-8
import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="root",
  passwd=,
  database = "ppl_flask01",
)
mycursor=mydb.cursor()
# mycursor.execute("CREATE TABLE book (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255), address VARCHAR(255))")
mycursor.execute("SELECT * FROM book")
myresult = mycursor.fetchall()

for x in myresult:
  print(x)

在这里插入图片描述

选取表中的部分字段,

使用“SELECT 字段1, 字段2 …”语句

mycursor.execute("SELECT name,address FROM book")
myresult = mycursor.fetchall()

在这里插入图片描述

只取一行

mycursor=mydb.cursor()
mycursor.execute("SELECT * FROM book")
myresult = mycursor.fetchone()

for x in myresult:
  print(x)

在这里插入图片描述

WHERE筛选数据

从表中选取记录时,可以使用“WHERE”语句筛选

sql = "SELECT * FROM book WHERE name ='三国演义'"
mycursor.execute(sql)
myresult = mycursor.fetchall()

在这里插入图片描述

通配符

WHERE语句中可以使用通配符%。关于SQL中,WHERE子句使用通配符

防止SQL注入

什么是SQL注入? SQL注入是一种攻击,当web服务器从浏览器接受用户输入时,如果web应用程序有漏洞,攻击者有可能注入恶意SQL代码。

SQL注入攻击可能引起敏感信息暴露,如用户的联系电话、电子邮件地址、信用卡信息等。利用它,攻击者甚至能绕过身份验证,访问整个数据库。

一种比较简单的方法
当用户提供查询值时,为了防止SQL注入,应该转义这些值。
SQL注入是一种常见的web黑客技术,用于破坏或误用数据库。
使用占位符%s方法转义查询值:

sql = "SELECT * FROM customers WHERE address = %s"

对结果排序

可以使用ORDER BY语句,按升序或降序对结果排序。
默认情况下,ORDER BY关键字按升序排列结果。要按降序排列,可使用DESC关键字。

sql = "SELECT * FROM book ORDER BY name"
mycursor.execute(sql)
myresult = mycursor.fetchall()
for x in myresult:
  print(x)

在这里插入图片描述

删除记录

可以使用“DELETE FROM”语句,从现有表中删除记录

sql = "DELETE FROM book WHERE name='John'"
mycursor.execute(sql)
mydb.commit()

删除表

sql = "DROP TABLE IF EXISTS customers"
mycursor.execute(sql)

更新表

可以使用“UPDATE”语句,更新表格内的现有记录:

sql = "UPDATE book SET address='Canyon 123' WHERE address='Valley 345'"

mycursor.execute(sql)
mydb.commit()
print(mycursor.rowcount, " 条记录已更新")

限制结果数量

可以使用“LIMIT”语句,限制查询返回的记录数量

mycursor = mydb.cursor()

mycursor.execute("SELECT * FROM book LIMIT 5")

myresult = mycursor.fetchall()

for x in myresult:
  print(x)

在这里插入图片描述
从指定位置开始如果想返回,从第3条记录开始的5条记录,可以使用“OFFSET”关键字

mycursor.execute("SELECT * FROM book LIMIT 5 OFFSET 2")

cookie和session

1.cookie:在网站中,http请求是无状态的。也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户。cookie的出现就是为了解决这个问题,第一次登录后服务器返回一些数据(cookie)给浏览器,然后浏览器保存在本地,当该用户发送第二次请求的时候,就会自动的把上次请求存储的cookie数据自动的携带给服务器,服务器通过浏览器携带的数据就能判断当前用户是哪个了。cookie存储的数据量有限,不同的浏览器有不同的存储大小,但一般不超过4KB。因此使用cookie只能存储一些小量的数据。

2.session: session和cookie的作用有点类似,都是为了存储用户相关的信息。不同的是,cookie是存储在本地浏览器,session是一个思路、一个概念、一个服务器存储授权信息的解决方案,不同的服务器,不同的框架,不同的语言有不同的实现。虽然实现不一样,但是他们的目的都是服务器为了方便存储数据的。session的出现,是为了解决cookie存储数据不安全的问题的。

cookie和session结合使用:web开发发展至今,cookie和session的使用已经出现了一些非常成熟的方案。在如今的市场或者企业里,一般有两种存储方式:

  • 存储在服务端:通过cookie存储一个session_id,然后具体的数据则是保存在session中。如果用户已经登录,则服务器会在cookie中保存一个session_id,下次再次请求的时候,会把该session_id携带上来,服务器根据session_id在session库中获取用户的session数据。就能知道该用户到底是谁,以及之前保存的一些状态信息。这种专业术语叫做server side session。存储在服务器的数据会更加的安全,不容易被窃取。但存储在服务器也有一定的弊端,就是会占用服务器的资源,但现在服务器已经发展至今,一些session信息还是绰绰有余的。

  • 将session数据加密,然后存储在cookie中。这种专业术语叫做client side session。flask采用的就是这种方式,但是也可以替换成其他形式。

flask中使用cookie和session

  1. cookies:在Flask中操作cookie,是通过response对象来操作,可以在response返回之前,通过response.set_cookie来设置,这个方法有以下几个参数需要注意:
  • key:设置的cookie的key。
  • value:key对应的value。
  • max_age:改cookie的过期时间,如果不设置,则浏览器关闭后就会自动过期。
  • expires:过期时间,应该是一个datetime类型。
  • domain:该cookie在哪个域名中有效。一般设置子域名,比如cms.example.com。
  • path:该cookie在哪个路径下有效。
  1. ession:Flask中的session是通过from flask import session。然后添加值key和value进去即可。并且,Flask中的session机制是将session信息加密,然后存储在cookie中。专业术语叫做client side session
from flask import Flask,Response,request,session

app = Flask(__name__)
app.config['SECRET_KEY'] = "12asdfadfdsfasd3"

#定义两个视图函数
@app.route("/set_cookie")
def set_cookie():
    response = Response("cookie 设置")
    response.set_cookie("user_id","xxx")
    return response


@app.route("/get_cookie")
def get_cookie():
    user_id = request.cookies.get("user_id")
    print("user_id:",user_id)
    return "获取cookie"


@app.route("/set_session")
def set_session():
    # 在flask中,session是先把数据经过加密,然后用session_id作为key,存放到cookie中
    # 因为session会经过加密再存储到cookie中,所以我们的敏感信息,会存放到session中
    session['username'] = "zhiliao"
    return "session设置成功"


@app.route("/get_session")
def get_session():
    username = session.get('username')
    print("username:",username)
    return "get session"


@app.route('/')
def hello_world():
    return 'Hello World!'


if __name__ == '__main__':
    app.run(debug=True)

在这里插入图片描述

wtforms表单验证

wtforms表单的两个主要功能是验证用户提交数据的合法性以及渲染模板,当然还包括一些其他功能:CSRF保护、文件上传等。安装Flask-WTF也会安装WTFroms,使用pip install flask-wtf或者

pip install wtforms -i http://pypi.douban.com/simple 
--trusted-host pypi.douban.com

一、表单验证

安装完Flask-WTF后。来看下第一个功能,就是用表单来做数据验证,现在有一个forms.py文件,然后在里面创建一个RegistForm的注册验证表单。
所有用到的代码文件:
在这里插入图片描述
app.py

#coding=utf-8
from flask import Flask,request,render_template
from forms import LoginForm

app = Flask(__name__)


@app.route('/login',methods=['GET','POST'])
def login():
    if request.method == 'GET':
        return render_template("login.html")
    else:
        form = LoginForm(request.form)
        if form.validate():
            return "登录成功!"
        else:
            return "邮箱或密码错误!"


@app.route('/')
def hello_world():
    return 'Hello World!'


if __name__ == '__main__':
    app.run(debug=True)

和form.py

#coding=utf-8

import wtforms
from wtforms.validators import length,email
class LoginForm(wtforms.Form):
    email=wtforms.StringField(validators=[length(min=5,max=20),email()])
    password=wtforms.StringField(validators=[length(min=6,max=20)])

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
<form action="/login" method="post">
    <table>
        <tbody>
            <tr>
                <td>邮箱:</td>
                <td>
                    <input type="text" name="email">
                </td>
            </tr>
            <tr>
                <td>密码:</td>
                <td><input type="text" name="password"></td>
            </tr>
            <tr>
                <td></td>
                <td><button>登录</button></td>
            </tr>
        </tbody>
    </table>
</form>
</body>
</html>
File "D:\666\ER-GIKT-Flask-Vue-main\Flask-BackEnd\app\setup.py", line 8, in <module> app = create_app() ^^^^^^^^^^^^ File "D:\666\ER-GIKT-Flask-Vue-main\Flask-BackEnd\app\__init__.py", line 53, in create_app from .view.kt_bp import kt_bp File "D:\666\ER-GIKT-Flask-Vue-main\Flask-BackEnd\app\view\kt_bp.py", line 16, in <module> model = torch.load(f=r'D:\666\ER-GIKT-Flask-Vue-main\Flask-BackEnd\app\alg\model\2025_03_21#12_46_20.pt') ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\anaconda3\Lib\site-packages\torch\serialization.py", line 1470, in load raise pickle.UnpicklingError(_get_wo_message(str(e))) from None _pickle.UnpicklingError: Weights only load failed. This file can still be loaded, to do so you have two options, do those steps only if you trust the source of the checkpoint. (1) In PyTorch 2.6, we changed the default value of the `weights_only` argument in `torch.load` from `False` to `True`. Re-running `torch.load` with `weights_only` set to `False` will likely succeed, but it can result in arbitrary code execution. Do it only if you got the file from a trusted source. (2) Alternatively, to load with `weights_only=True` please check the recommended steps in the following error message. WeightsUnpickler error: Unsupported global: GLOBAL gikt.GIKT was not an allowed global by default. Please use `torch.serialization.add_safe_globals([GIKT])` or the `torch.serialization.safe_globals([GIKT])` context manager to allowlist this global if you trust this class/function.
03-22
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值