技术标签: ORM与SQLAlchemy (1) - 建立第一个模型 Python Flask
后端一个重要的点就是与数据库联系,例如网页的注册、登录,内容的更新等都需要与数据库建立关系。以MySQL
数据库为例,平时我们会用mysqldb(python 2)
或者pymysql(python 3)
去操作MySQL
数据库,但这种方法也是需要自己编写SQL语句的。现在我们有了ORM模型,简单来说,ORM是把数据库中的表抽象成模型,表的列名对应模型的属性,这样我们可以调用类的属性或方法去获得数据库中的数据。例如假设MySQL
数据库中有一张表名为table1
,使用SELECT * FROM table1 WHERE id=1
获取id
为1
的数据,如果将表table1
映射成ORM模型Table
,那么可以直接使用Table.query.filter(id=1)
,这样操作简单了很多,也很利于理解。
SQLAlchemy
就是一个这样的ORM,我们可以直接安装flask_sqlalchemy
来使用。在这之前我们先在MySQL
中手动建立一个数据库harp
,在建立的时候把charset
设置为utf8
,避免存入中文时变成乱码,然后在配置文件config.py
中填写好数据库的连接信息:
HOST = "127.0.0.1"
PORT = "3306"
DB = "harp"
USER = "root"
PASS = "Your Password"
CHARSET = "utf8"
DB_URI = "mysql+pymysql://{}:{}@{}:{}/{}?charset={}".format(USER, PASS, HOST, PORT, DB, CHARSET)
SQLALCHEMY_DATABASE_URI = DB_URI
SQLAlchemy
依赖mysqldb
或者pymysql
去连接数据库和执行SQL语句,因为我们用的是python 3
,所以需要在配置信息中指明使用pymysql
,如果是python 2
可以省略,默认是使用mysqldb
。
建立好了数据库,我们开始建表,首先建立一张用户表,我们设想它应该有id(作为主键)、用户名、密码、注册时间这些基本的字段,有了ORM,我们就不用再写SQL去建表了,在项目的主py文件中添加以下代码:
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
import config
app = Flask(__name__)
app.config.from_object(config)
db = SQLAlchemy(app)
class Users(db.Model):
__tablename__ = 'users_info'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
username = db.Column(db.String(32), nullable=False)
password = db.Column(db.String(100), nullable=False)
register_time = db.Column(db.DateTime, nullable=False, default=datetime.now())
db.create_all()
解读一下这段代码,导入SQLAlchemy
和含有数据库连接信息的config
,实例化一个SQLAlchemy
对象名为db
,其传入的参数为Flask
实例app
。接下来定义了一个User
类,这个类就是ORM中的模型,也就是数据库中的表映射的模型,它需要继承自db.Model
,__tablename__
这个属性就是建表后,数据库生成的表名;然后使用db.Column
来实例化id/username/password/register_time
这几个列,db.Column
的参数描述列的类型、主键等信息,如db.Integer/db.String(32)/db.DateTime
分别代表整形、字符串(最大长度)、时间,primary_key=True
说明该字段为主键,autoincrement=True
代表自增长,nullable
决定是否可为空,default
代表默认值。最后用db.create_all()
来实现创建。我们暂时不用理解为何SQLAlchemy
需要传入Flask
实例作为参数,为何模型要继承自db.Model
,重要的是可以先把想要的表建立起来。
进入数据库,输入desc user_info;
,我们发现表已经建立好了,其结构图如下:
但它现在还是空的,我们来试着插入一条语句,将视图函数修改为:
@app.route('/')
def index():
user = Users(username='Harp', password='123456')
db.session.add(user)
db.session.commit()
return render_template('home.html')
代码实例化一个Users
的对象user
,传入username
和password
,使用db.session.add(user)
将其加入到数据库的session
(可以理解为事务)中,然后使用db.session.commit()
提交。我们运行程序,然后用浏览器访问,浏览器正常显示了结果,这时再看一眼数据库,发现这条数据已经写入到了数据库:
查询、修改数据也同样很简单:
@app.route('/')
def index():
user = Users.query.filter(Users.id == 1).first() #查找
print(user.username)
user.username = 'Harp1207' #修改
db.session.commit() #修改后需提交
print(user.username)
return render_template('home.html')
思考问题:
1.为何要把模型的操作语句放在视图函数中?(搜索上下文这个概念)
2.数据查找,我们用的是Model.query
,其实还可以用db.session.query
,两者有何区别?filter和filter_by又有何区别?
文章浏览阅读712次,点赞8次,收藏9次。通过将图像切成patch线形层编码成token特征编码的方法,用transformer的encoder来做图像分类multihead和我原有的理解偏差修正。我以为的是QKV会有N块相同的copy(),每一份去做后续的linear等操作。代码里是直接用linear将QKV分为一整个大块,用permute/rearrange的操作切成了N块,f(Q,K)之后再恢复成一整个大块,很强。_vision transformer论文
文章浏览阅读180次。今天在安装好了es,启动和配置花了点时间,这里记录一下。配置elasticsearch.yml,参数大致如下:属性说明cluster.name集群名称,默认elasticsearchnode.name节点名称node.attr.rack节点服务器所在的机架信息path.data索引数据存储路径path.log日志存储路径bootstr..._es安装完
文章浏览阅读1.2k次。【代码】php程序控制打印机自动打印。_php实现打印机打印
文章浏览阅读2.9k次。Frequency Separation for Real-World Super-Resolution[PAPER]_frequency separation for real-world super-resolution
文章浏览阅读6.7k次。本文主要讲述如何使用命令查看虚拟机是否能够联网,及虚拟机的网卡配置。本文主要介绍,如何查看虚拟机网卡,及测试上网功能。_怎么看虚拟机有没有连接到网络
文章浏览阅读3.2k次。导读:在SaaS的经营中,对数据的整理和分析可以帮助我们有效地了解企业经营现状和可能存在的发展机遇。对于企业的不同角色和不同发展阶段,其需要关注的数据指标会有所不同。下面我将根据自己多年从..._支付产品 核心指标
文章浏览阅读614次。策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,将每个算法封装起来,并使它们可以互相替换。策略模式使得算法可以独立于使用它的客户端而变化。总之,策略模式可以帮助我们将算法的定义、使用和变化分离开来,提高代码的可维护性和扩展性。
文章浏览阅读1k次。As shown in the image below, the legend is too long for the plot window. what I want to do is:1- To know how to split the legend over a second line?2- To know how to shorten the red line in indicated ..._matlab 图例大小
文章浏览阅读1.4w次,点赞4次,收藏16次。前言matplotlib处理经常能够用到的折线图、柱状图等,还可以画出直方图和密度图。plt.hist()方法matplotlib.pyplot.hist(x,bins = None,range = None,density = None,weights = None,cumulative = False,bottom = None,hist type =‘bar’,align =‘mid’..._将一个数组,绘制成密度图 matplot
文章浏览阅读387次。1.问题给定一个表示分数的非负整数数组。 玩家1从数组任意一端拿取一个分数,随后玩家2继续从剩余数组任意一端拿取分数,然后玩家1拿,……。每次一个玩家只能拿取一个分数,分数被拿取之后不再可取。直到没有剩余分数可取时游戏结束。最终获得分数总和最多的玩家获胜。给定一个表示分数的数组,预测玩家1是否会成为赢家。你可以假设每个玩家的玩法都会使他的分数最大化。力扣(LeetCode)原题链接;2..._486 预测赢家(动态规划)
文章浏览阅读445次,点赞7次,收藏3次。如果你也想学习:黑客&网络安全的SQL攻防知识宝库在此藏,一键关注获宝藏是一种Web应用程序中的安全漏洞,它允许攻击者通过在用户输入中插入恶意的SQL代码,来执行非授权的数据库操作。具体来说,当应用程序将用户输入的数据直接拼接到SQL查询语句中而没有充分验证或转义时,攻击者可以利用这个漏洞来修改原本的查询意图,甚至获取、修改或删除数据库中的数据。SQL注入攻击的原理是用户输入的数据被当成SQL代码执行。_sql注入删除
文章浏览阅读2k次。第一步:下载npm包npm install mxgraph --save第二步:新建一个index.js文件文件内容如下import mx from 'mxgraph';const mxgraph = mx({ mxImageBasePath: './src/images', mxBasePath: './src'});// decode bug https://githu..._vue3.0 ts引入mxgraph