|
|
1.介绍
4 ~7 P- q, A7 j) o% V) Qflask用于orm操作表,一般使用flask- sqlalchemy 操作简单
6 s3 m) n7 X: O; y一般使用flask-sqlalchemy 2.5.1
9 Q" \" W2 W; r) q3 Mhttps://flask-sqlalchemy.palletsprojects.com/en/2.x/! k _& S. J# V0 D% ]: D0 F
, A h# j, V: }) k2 u( i2 I! C# h/ t. G+ G j
: M0 k7 h: I3 O0 ~& y. k* W
2.安装6 ~3 w: X4 N5 I3 u" ~- y S
pip instal flask-sqlalchemy==2.5.1
; d0 U' `8 L0 X. v, Ypip install Flask-Migrate==2.6.0 # 迁移数据库使用
4 O0 p8 L7 ~# S* ]9 G* y n0 z! I
. ]: L( L7 V6 ~, @
3.数据库( q6 b( Q! m: {9 C
1.配置 连接数据库
; l2 M' P3 j, N. k4 u9 `代表驱动
: O$ w' `: j4 V$ ^" MMySQL-Python # 可以写mysqldb
9 m Q6 D) U t6 w mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname>8 c( n: I- T, y: ~' d/ k8 E- q
9 r4 U8 q7 b( a, _+ {4 A
pymysql9 L% @; Q3 l7 x& j0 L
mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>]
. c5 v( Y/ J! L; C/ S7 |% K* ?' u7 g; _5 m, |2 a0 G
MySQL-Connector
$ X# H1 B( `6 X4 M9 Y( t! k1 A mysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname
- U' ^+ z* \$ ^* G4 m9 j$ w: M. d1 l
2 Z# }8 f/ h1 k/ [! b4 b& f* S4 p- b
需要安装不同的扩展 注意mysqlclient的版本
2 B; h. l5 b% o可以放到配置类里面: d6 k; w' E7 B* \. u
' ]; }0 \- ?9 r# n5 z7 g; X' \
方法一 3 B( ?- g: n c0 s- x
SQLALCHEMY_DATABASE_URI = 'mysql://user:密码@localhost:3306/库名?charset=utf8mb4'
( {5 I$ ~+ F3 j! t- W. g# u$ B8 S% Y- l
6 r5 q! s' j$ d% q/ B方法二
% B! ?' w: ]$ P7 U( G XDIALECT = 'mysql'
4 ^4 A. q% u& E" i% _/ `! X+ p8 |DRIVER = 'pymysql'
. i7 X& K' E) Z- B0 gUSERNAME = 'root'
% g1 [* O4 {8 P8 ~7 ^PASSWORD = '****'' z N5 Z Q2 J: [ ^
HOST = '127.0.0.1'
5 M3 l* d# w) }! K( ]% D3 TPORT = '3306'! D! X% u, C& x& _4 f& I: W# B
DATABASE = '数据库名'% g% X: g+ p$ t4 U
- U( f. x# j' E2 M" Y5 c: sSQLALCHEMY_DATABASE_URI = "{}+{}://{}:{}@{}:{}/{}?charset=utf8".format(DIALECT,DRIVER,USERNAME,PASSWORD,HOST,PORT,DATABASE)
* v( L+ C6 s& x% I- ?7 u' j# a% A7 w' T
- f5 I0 b6 F, T0 S' t0 |' R6 y
: l: }0 W2 s/ _2.连接数据库
. z9 m% r, }4 J) K7 E, [1 t1 实例化SQLAlchemy对象 可放入其他文件2 i# _& k! x; r) f$ @ g3 H
from flask_sqlalchemy import SQLAlchemy
2 W4 E$ S b. P% X3 v }db = SQLAlchemy()) M0 y( B; {1 h' @% B
& a. g3 w# S# Q1 x
2 注册db: y# y( w4 j* l% Q! e- t
! H. T& P ?. ^/ e3 I# 初始化迁移数据库
6 S8 X6 n7 Y- g. Kmigrate = Migrate()
6 h& F$ A# a$ g6 s, |" a
' p4 ~+ z9 d) m/ A2 U; Q/ D2 F% Jdef create_app() -> Flask:
" T0 u9 ]5 K$ c, t# e app = Flask(__name__)
) r, @1 g w# T, S( ^ c app.config.from_object(Config)
% |( O7 y4 f+ k. n1 y$ ]5 o # 绑定数据库
- N: f% N: f' e6 g6 r8 { db.init_app(app)8 y4 f$ y/ b6 V3 v5 D
$ `* ~- q1 W+ z1 r+ ~ R
# 迁移数据库
+ d) X2 [2 h+ B6 [" j migrate.init_app(app, db)
8 ^, ^2 B0 W0 ~ return app
- b$ z1 c, p7 ^) w5 ?4 e: Q( X8 J7 x
) k+ R; H! g* O# B, W( {注意命令可能无法迁移
- t6 G3 W% E7 X/ L7 W1 q1 ~/ B! F) K2 Q+ I6 F: N0 K
1. 命令行一直报 , u# D% O1 G# \' ]5 v e
# Error: Could not locate a Flask application. Use the 'flask --app' option, 'FLASK_APP' environment variable, or a 'wsgi.py' or 'app.py' file in the current directory.
- I v4 P' v T7 y6 H/ P) j$ j( @- K: @! f
这是在虚拟环境没有配置
3 }! W4 a2 N \6 P8 }! S. x8 ?2 i7 |. t6 T" g
使用 .env 文件 来设置数据
5 Q7 ?" a! M' @) X J# 下载 插件8 `/ m9 H. s- V3 n8 M7 s* j
pip install python-dotenv
! ]* e' z% M' k+ k8 S$ _- v: [% ?
) i, @6 ?3 j, ^; B4 R4 X# 创建app' P8 R7 `: A2 ?; m: Y$ P
def create_app() -> Flask:0 `) H& Y" D+ Y' M, r3 V9 H0 _6 z
app = Flask(__name__)/ I% c. F I3 w6 C- R; A
# 要在最开始加载 后面才能获取到
( _9 y6 \ {% n( d5 _9 K; j load_dotenv(verbose=True)
# w N) k9 s8 I* w% c, K# ?# ?$ ?/ m5 W' U5 X( o3 F+ k* Y
# 注册配置文件 生成/测试
: k8 A0 l! q8 n9 b6 ^ # env = str(os.environ.get("FLASK_ENV"))
- H( d4 d& [4 g9 Y5 y. Q env = str(os.getenv("FLASK_ENV"))3 L. w) J) `5 t) i2 v- H# q+ F
app.config.from_object(getattr(conf, env))
2 z0 |1 D: ]5 _0 Z! q; D
7 |$ c, m7 |2 D, S' V # 绑定数据库$ ?) Y* @- `; |# G- H
db.init_app(app)
" U& X6 E* t: _; f2 r/ V
2 ?. U: O* N- e9 c. o # 迁移数据库5 Z- {5 p6 Q2 e0 d
migrate.init_app(app, db)
$ K1 ^% N9 i& k- g# R& I `3 @ return app& Q; [3 y3 k1 X. h4 n
#-------------------------------------9 D" F# T! `' c* X( t$ k
# .env 文件
9 I% R2 h4 u1 L& V T; }+ p3 G9 L5 g% j6 _
FLASK_APP=main.py # 自己的启动文件 默认是app.py8 Y- L3 c2 z) e5 q! K
FLASK_ENV=development7 _2 F* m) G) h% |2 v# V
FLASK_DEBUG=True. }: F' [0 D* G0 V0 q
" k: A; C) x4 D H
! P+ v* j' L9 O3 m5 E4 I4 h
这样就可以输入命令了" W' [0 A4 i# r) T% \
" _ k0 Q3 ]$ R0 B4 O: R
报错误 either 'sqlalchemy_database_uri' or 'sqlalchemy_binds' must be set.8 O: F/ v$ A- q" q! W |
没有把模型放到 view文件里面 只想要把 模型导入就好了,可以不使用
) b# R) ]/ r5 d3 B- r- f# T; q0 Kfrom user.model import User
; b/ u! e/ p6 c: _ Z& e, a2 j+ z7 X* v
; u% Y, G9 Y; Z; a& F2 I+ S) w1 Y3 迁移数据库
% ]) f& O' }- p3 a# r. x# 初始化一个迁移脚本的环境,只需要执行一次。. G+ a& O% _/ Q3 N+ X5 W7 e; w$ K! v, ~
flask db init% r4 N: B& h! l& R I0 l4 i
# 将模型生成迁移文件,只要模型更改了,就需要执行一遍这个命令8 G6 K' ]0 D0 q
flask db migrate -m'迁移数据库'
' A- V+ t- Q, `) M# 将迁移文件真正的映射到数据库中。每次运行了migrate命令后,就记得要运行这个命令。( H3 L" I" I2 ~# y4 E- d5 R* j
flask db upgrade9 ], O, v0 t' Q# m! i, n. e4 M
#-------------------------------------
. D% A8 S$ {; w/ D( Zflask db heads 查看当前最新的迁移id
3 S9 i9 J8 a( B Q+ g& @1 W! {. Oflask db stamp heads # 更新( G5 v. `- t$ o2 j9 q& v& w
flask db current # 查看当前迁移id
. T+ o- v! K o) ], Z/ Qpython manage.py db history #查看历史
+ r1 w7 n7 d3 P/ Epython manage.py db downgrade 652a55840d #回退版本* ^: G% Y' P" x, Q
4 R! i) F! h, y7 Z, `# n( S" |2 n1 W Z H, w
4 数据库其他信息/ Q( r9 C0 |8 q5 A9 Q3 x
# 查询时会显示原始SQL语句
0 ^- z7 `; s6 ?/ l2 U. zSQLALCHEMY_ECHO = True) a7 Y _7 [5 v
# 动态追踪修改设置,如未设置只会提示警告
* W& h2 ?+ T6 S1 y5 L. DSQLALCHEMY_TRACK_MODIFICATIONS = False6 _0 N' `7 R2 \
# 数据库连接池的大小: g* P4 q+ t0 r, Y B5 }
SQLALCHEMY_POOL_SIZE = 10
_! I* K, v$ h# 指定数据库连接池的超时时间
2 U4 g; B. O2 t' ^0 H. G" xSQLALCHEMY_POOL_TIMEOUT = 103 E& Q9 v ~' h
# 控制在连接池达到最大值后可以创建的连接数。当这些额外的 连接回收到连接池后将会被断开和抛弃。
; r% ~5 j% @) h+ ySQLALCHEMY_MAX_OVERFLOW = 24 @9 ~( g3 \' J% C) |' C3 c
) ]: m* }. n6 q. |+ V/ C+ y) \6 W6 ^+ O1 d: e5 \/ m5 b
名字 备注* F- Q0 Z0 J! W% _/ R: w$ Q. Z
SQLALCHEMY_DATABASE_URI 用于连接的数据库 URI 。‘mysql+pymysql://root:密码@localhost:3306/库名?charset=utf8mb4’
( Y/ p' v+ b6 t* r6 |) ?SQLALCHEMY_BINDS 一个映射 binds 到连接 URI 的字典。更多 binds 的信息见用 Binds 操作多个数据库。
- ^. m5 p8 `& E! ]. ^SQLALCHEMY_ECHO 如果设置为Ture, SQLAlchemy 会记录所有 发给 stderr 的语句,这对调试有用。(打印sql语句)# p9 Y8 \# ~1 m. n6 k: ]/ i9 q
SQLALCHEMY_RECORD_QUERIES 可以用于显式地禁用或启用查询记录。查询记录 在调试或测试模式自动启用。更多信息见get_debug_queries()。
( x2 ]" h3 c# H& QSQLALCHEMY_NATIVE_UNICODE 可以用于显式禁用原生 unicode 支持。当使用 不合适的指定无编码的数据库默认值时,这对于 一些数据库适配器是必须的(比如 Ubuntu 上 某些版本的 PostgreSQL )。" M7 t4 M& b7 @/ i! R. B
SQLALCHEMY_POOL_SIZE 数据库连接池的大小。默认是引擎默认值(通常 是 5 )
9 ?/ ]$ [/ V( S: USQLALCHEMY_POOL_TIMEOUT 设定连接池的连接超时时间。默认是 10 。
3 r0 D5 }8 N4 C3 r2 J) L$ j, USQLALCHEMY_POOL_RECYCLE 多少秒后自动回收连接。这对 MySQL 是必要的, 它默认移除闲置多于 8 小时的连接。注意如果 使用了 MySQL , Flask-SQLALchemy 自动设定 这个值为 2 小时。
% V+ x) [- J. |4 创建表
1 Z+ b f$ m0 B8 I- u" gfrom core import db #这里需要引入实例化的SQLAlchemy对象
5 l% D- K6 S8 O/ ^) R" B- U* R7 C7 t" e: b/ b7 M- P
class User(db.Model):" W9 W3 o/ D( b
"""用户表"""( a8 K! h- A3 F5 v- H' ?# w. {; q3 [/ p
__tablename__ = 'user' # 创建后表名 小写4 W* k+ ^& [* R. G9 e C: J* l
# __abstract__ = True # 抽象表 不创建这个表 可以继承) U" w% z5 G1 a! g7 c4 w+ I
6 D% o0 S+ Z* [& ?4 I# T" B
id = db.Column(db.Integer, primary_key=True, comment='id主键') # 必须要有
: Y* l' X& z# n( Q username = db.Column(db.String(32), unique=True, comment='用户名')! k+ J5 z G: }* f! P* ]
password = db.Column(db.String(64), nullable=False, comment='密码') I% b) _# K4 G( s1 k
gender = db.Column(db.Boolean, default=0, comment='0 男 1 女'). J- {: J% @: u1 S: _' Q
avatar = db.Column(db.String(125), default='http://s5p.hd-bkt.clouddn.com/default.jpg', comment='头像')
! N6 Z5 S: J' h( e, j+ Q$ [0 ^ addr = db.Column(db.String(256), comment='地址')7 v# v. h, m2 z0 H! V
email = db.Column(db.String(125), comment='邮箱')4 U% X+ ?" x$ y6 Y A
mobile = db.Column(db.String(11), comment='电话')( N5 V& a. E& G* r; ]/ B8 ?
login_type = db.Column(db.Integer, comment='1 电话 2 邮箱 3 用户名')7 L' G1 c. W$ P! ^! q0 Y
& z: @$ E F) y. q5 H def __repr__(self): # 查询的返回 和str一样% I5 H: I" W! g, U
return f'<{self.__class__.__name__} {self.username}>'( h. S1 S, z0 v- Q1 k' O' E" C" ?
+ Z6 m. ?( ]* ~1 _+ O+ O; @3 ~5 n1 w, Y9 o& y7 W) @" |4 v! M9 \
1.字段解析
; U( r' f' ^& s& ?类型名 python中类型 说明: o2 t* v; K# u" }* Y6 X; P
Integer int 普通整数,一般是32位0 G3 c6 |! {+ }8 X
SmallInteger int 取值范围小的整数,一般是16位 |9 M9 G2 N$ L: L6 e9 X
BigInteger int或long 不限制精度的整数
! P0 f: I* j( ~Float float 浮点数
! I9 T" m* \* v" ^Numeric decimal.Decimal 普通整数,一般是32位" u4 [! Q; L c+ P$ a3 ]( s+ h
String str 变长字符串
6 U7 N/ S* F8 ~6 i+ @1 S8 t8 d1 ?* Z- sText str 变长字符串,对较长或不限长度的字符串做了优化
1 ]% C/ B# Z- G# p3 @7 uUnicode unicode 变长Unicode字符串
; ?. N* U+ X$ a& oUnicodeText unicode 变长Unicode字符串,对较长或不限长度的字符串做了优化
6 g2 S9 v, y$ J7 zBoolean bool 布尔值
% u& Q8 p$ p2 E4 q: ~# |" w2 qDate/DateTime datetime.date 时间
, \' _; T) d2 q9 u& K$ pTime datetime.datetime 日期和时间
4 V3 H0 ^- f7 Y% ]0 i4 j/ zLargeBinary str 二进制文件
$ x) A8 b0 ?2 N$ G2.表属性. S+ H- R+ ]8 t' G1 ?8 H8 v/ N1 {
选项名 说明( l0 o/ c* U# i2 ^
primary_key 如果为True,代表表的主键
9 e7 y, w/ F0 M2 R A' {/ y# Dunique 如果为True,代表这列不允许出现重复的值
1 {. t% Y! b5 c2 `& y% Zindex 如果为True,为这列创建索引,提高查询效率
4 w" S: f* A2 tnullable 如果为True,允许有空值,如果为False,不允许有空值
* d8 L3 T; J0 O- Zdefault 为这列定义默认值
/ G5 X( r0 M* K" D5.查询3 y1 R4 B" D7 T4 h4 r
注意只要对数据库操作就需要 db.session.commit()( A; Z& P! E1 J' L( W
/ _9 x$ ^/ @1 W1 R4 V% D2 h& H
查询方法( P; A7 g& O+ ]$ ]' X( ]/ b6 L
方法 说明9 i8 \& G* C- P4 h( Q6 k+ Z
all() 以列表形式返回查询的所有结果7 A6 n0 z" j3 Q; I6 M7 }
first() 返回查询的第一个结果,如果未查到,返回None
' [. r$ ]- { K( E& }' J# cfirst_or_404() 返回查询的第一个结果,如果未查到,返回404
4 M: ~$ r. l. G, Kget() 返回指定主键对应的行,如不存在,返回None- o2 z# B- _+ U; q! Z( T9 P: h
get_or_404() 返回指定主键对应的行,如不存在,返回404& X) u% e3 u" a& O/ R/ w
count() 返回查询结果的数量
4 `$ X9 t% Z. v0 K% Qpaginate() 返回一个Paginate对象,它包含指定范围内的结果
* I- A' ~+ `) w6 O s G! Z$ T# B1.普通查询
+ f% o0 ^9 ?* ~) M3 b- K9 |# m# 查询数据条数* n- p) ~, j2 A4 K, ?$ g2 C
User.query.count()
' ]; U- m$ Q5 Z6 g0 ]" y' [7 M, r- H- N$ q( K! |% Z- M* Y
# 查单条 获取不到none0 I' G2 \( ]: e. a" |5 X
user = User.query.first()
- t& {$ {, C6 u* ]' F. zuser = User.query.filter(User.username=="小红").first()5 a p( ^/ f' }
user = db.session.query(User).filter(User.username=="小红").first()+ `& t& W! u" M; B6 F. J
'''
a0 ^ p# q+ [6 Ddb.session:是一种更明确的查询语法,适用于更复杂的查询场景,或者在不直接访问模型的情况下执行查询操作
6 x6 H+ a4 ]# x% F'''
( F. c, o9 K1 C0 c" W$ h1 F$ E( q
# 查所有
& Z1 |- D: t& ? t% d2 ?2 V& Cuser = User.query.all()6 A# V# b# ^7 n8 j0 k( H! s$ g
user = User.query.filter(User.username=="小红").all()
- h9 B! s8 P. Y0 [) l* G$ F3 luser = db.session.query(User).filter(User.username=="小红").all()
4 ?6 z+ y2 \0 h! `
8 r& p) L- t8 q1 P) }0 o5 ~7 i# 只获取单条3 ] l: I" f1 e7 w; C; |
# 结果为一个时正常,多了就报错, |$ a) U2 b' N$ R' ?
# one_or_none() 获取不到报错2 D2 B: M0 y F. P- N; G0 D! y1 Z+ A
user=User.filter(User.username=='小红').one()
9 `& \- i7 \4 p: e8 ]1 B4 Z' L# \
# 获取不到报错
]. P o8 J* F7 `# get里面需要参数 是id6 c9 L o! n4 T3 g0 j: L) G
user = User.query.get(2)
) b g/ m4 l9 a
; @: x; T G, C5 z6 R4 d
9 O/ p5 Z2 `1 |5 i4 h7 Y
% s0 j$ Z8 T; U8 N, b/ G8 x" E2.条件查询* v) i+ r! T6 R: z' F3 U8 [
# 条件查询0 {& d& ~# r% T, U6 i
user = User.query.filter(User.username=="小红",User.password=="123").first()
; c1 `: k5 ?) g( I9 u# 不等于
& l1 o+ {" ?; }! e, [# l( R) W1 X user = User.query.filter(User.id!=2).all()
; l7 Z5 r. x. H% _7 D. U( J. E! [6 g2 P# 大小于$ e ^5 t5 G4 w3 Q2 |
user = User.query.filter(User.id>=2).all()
8 V/ b) v$ X5 { user = User.query.filter(User.id<=2).all()
' z* e2 ~# w4 o0 B; O/ r3 [0 @4 M7 w+ }9 m- @
#----------------------------------------
- c" N; j2 T5 M9 ^+ ~# 结尾为红0 ?. Y8 u9 [7 A2 H! d/ p
User.query.filter(User.name.endswith("红")).all(); g- @' _/ U# Y5 E
User.query.filter(User.name.like("%红")).all()4 [8 D5 d/ T) I5 U: T l4 ]
# 开头为小0 X+ X3 }1 c7 }. {# m8 Z
User.query.filter(User.name.startswith("小")).all()
: x1 i# { b7 P; c) X$ u7 cUser.query.filter(User.name.like("小%")).all()3 J0 {) |3 c! q6 w5 E, r( J8 v: V4 G
# 包含n mysql语法
/ A* z' O7 L. u0 w# |: ]User.query.filter(User.name.contains("n")).all()) k, ~: a# Z& d+ _1 r0 S& }! X% F
User.query.filter(User.name.like("%n%")).all() # 模糊查询
6 S$ R0 I8 d- o# F _" T
! V6 O$ }! |5 X) ^#-----------------------------------------1 t0 w+ x, \7 P- a4 P0 a& d4 ?0 i
# 成员属于 in_, C; }# x( ~! L& \! L
User.query.filter(User.username.in_(['aaa','bbb']).all()' v6 w* E* Q9 g
#成员不属于 notin_ n. D3 A# H' O( y$ T1 Z2 a! m
User.query.filter(User.username.notin_(['aaa','bbb']).all()+ d% y% O' y) \/ Q c# o
# q2 x$ L1 b8 v#----------------------------------------# l6 C$ I. ^; S0 O( W' i8 L' A1 N8 m
from sqlalchemy import and_, or_, not_" c- l1 {2 k- ^$ h6 |- w
# 和0 Q6 g% s5 @" t- V
User.query.filter(User.name.startswith('a'), User.email.startswith('q')).all()6 ?& C4 T# F) Q$ q3 ]: k- X
User.query.filter(and_(User.name.startswith('a'), User.email.startswith('q'))).all()
2 L. L5 m Z1 k$ F9 W( f8 V3 I# 或者3 I- W; p% n7 |+ K) p1 _
User.filter(or_(User.username=='qaz',User.password=='qwe123')).all() 8 `/ P: Q% [- o- z3 M! U+ x
# 非
$ H6 a, S/ I; FUser.filter(not_(User.username=='qaz',User.password=='qwe123')).all()
0 i# b4 \( W7 f5 G2 @' A ]( F0 Z F5 l' h1 P/ S3 n
#是否空判断
9 F1 q' ^, ]. U' p$ k) UUser.filter(User.username==None).all() )" D \( p* p k5 g- t1 G
User.filter(User.username.is_(None)).all() ). i A7 ^- s5 U- G! ~5 }
User.filter(User.username.isnot(None)).all() )
- j, Q5 @/ P) w. c, e0 R5 {
! L) z) a1 R; Y5 z# \, R- u#------------------------------------------
3 Y; L3 s( r: u) u2 [2 X# limit 限制返回数据条数
# L8 J' X4 T* `2 n0 k7 [6 j5 E+ }, G# 开始条数是0" B( x# E$ [2 v0 y V9 K
User.filter(User.gender!=1).limit(2).all())
- M- r! q* L2 T" r% u# 从第几条开始获取 偏移
" [6 ]4 d3 H% P _$ `: mUser.query.offset(0).all()7 b" z* ~$ J' S% o# t4 J
# 从第2条数据到第3条 包前不报后( @8 Z7 { I' l# [
User.filter(User.username!='qq').slice(2,3).all())
- y4 Y4 z6 l1 [1 m: Q- L
. r9 H. V8 y% ?8 `3 K0 S @# _# 排序 order_by 默认正序2 Y0 y- z! R2 ^7 r, {
User.filter(User.username!='aa').order_by(User.username).all()0 t( L2 e l' f& _& G* w- c; N
User.filter(User.username!='aa').order_by(User.id.asc()).all() 正序# A% r$ V, U' C" e e: `. e
User.filter(User.username!='aa').order_by(User.id.desc()).all() 倒叙( l, J/ {( d' ]+ u4 u
' e6 X& u: @) e# 注意:上面的可以随意组合7 v7 l5 b. b" k" {/ q0 S
# 其余后续补充
# t, p6 ~* |" g8 R! A D% g, @) b# W7 t0 ?2 {
5 q1 V; V$ X: F5 L- K1 Q3.filter和filter_by
' q& ?& A# Y5 T( ^; Afilter_by和filter都是过滤条件5 y( i- p7 B; [; B' ?6 S: X# j3 c
filter_by 不支持比较运算符,只能用=
; \1 n. t1 G8 E1 [* J
5 {7 h& y1 v5 e* L6 n4 H) o6 ?# 返回的都是对象
: S) ^+ B1 W% ^rows1 = User.query.filter_by(username='小红').all()1 V- I5 p2 S/ O
rows2 = User.query..filter(User.username=='小红').all()( Q" S7 U1 G7 Q8 [# d
2 I8 h/ A" ^, ^$ P, H! y# rows3 返回的是User的username属性,不是对象* n& A9 ^+ A a& |
rows3 = db.session.query(User.username).filter(User.username=='小红').all()
6 e/ q1 |' W& {* x" ~ e# 返回的是select语句
$ ~+ p# w [: i# C. P6 f9 e crows4 = db.session.query(User.username).filter(User.username=='小红')7 ]1 J$ c& `+ [7 K4 d5 F
8 ?2 O2 F$ Q) R0 q6 P8 u7 N9 ?- c
. B" ~5 N9 x$ U1 F1 @2 ^- U0 n6.增加
/ s1 X' `4 c& l# 单数据增加
$ v2 P- F S* F user = User(username="张三",password ="123",email="123@qq.com")+ q+ c( ]4 S8 M$ K# t' E \( J
db.session.add(user)
' r0 K) ^* X+ @( S1 ] S db.session.commit()
0 {* G8 G9 c* ~6 M' \3 x: ]) y4 b* R% u! V. Y
#-----------------------------------% I$ U( B, y, A, y7 t' Q5 E4 L
# 多数据增加* @5 i4 z" b* @1 S' w4 u( u+ g
# 后面两种可能会有颜色警告+ L2 L O5 L6 U9 ~
方法一:使用字典列表一次性插入多条数据0 ?6 D$ R; f8 n) A% K$ Q4 T
@bl_user.route('/index')8 `. P& y( G" Q
def index():
8 l- A/ z! D+ O data_list = [3 r; A$ I6 W& K$ w+ a
{'username': 'value1', 'password': 'value2'},# o8 k; Y. C( Q+ j
{'username': 'value3', 'password': 'value4'},
3 [5 x/ R+ {$ t- o) s* { ]$ q9 H# j4 i7 K, h6 u
db.session.bulk_insert_mappings(User, data_list); i: m5 t& ?, h5 @* u p
# db.session.bulk_insert_mappings(模型, 数据)9 }, C6 p$ B6 p5 d
db.session.commit()5 S/ c$ j4 A. F' l0 u. f
return '增加成功'
) P6 k7 Q) W# b9 B/ X% x3 L
7 b2 [; E: W% B方法二:将多个对象一次性保存到数据库0 W7 a& p6 L C N% B: m+ y' d
@bl_user.route('/index')
# s0 m9 \- a- l+ n4 B7 }3 [) x2 |def index():9 g3 q: H: T4 ], o% y8 j
data_list = [
( [! q1 p2 m1 T" x0 e* {+ Q User(username='value1', password='value2'),
* s9 b, ?# {( ^" P4 b2 i3 C0 ^5 B User(username='value3', password='value4'),
5 K% z; N4 d' @3 p L* r ]6 X: L* \( ]% G& f: i9 Z. F" L5 F
db.session.bulk_save_objects(data_list); N" M; _8 [$ X# B
db.session.commit(), ]0 d9 U+ ^2 t7 P- M
return '增加成功'
% o3 ~, u" ^( U7 m( p2 @
' ]: i) f/ E, s. G3 d9 }方法三:
- }! Z8 J& E+ U% T) F- Y+ a h@bl_user.route('/index')
4 U9 K& S, |5 Y, c data_list = [+ z8 T" {& L7 W4 o9 r* M+ Y _9 v
{'username': 'value1', 'password': 'value2'},- x. S6 B# o5 y/ p6 D4 ]; n
{'username': 'value3', 'password': 'value4'},: U4 m# M9 h7 e/ m' A
]. T, O: p# w' v, I3 `" A& B
# c N# I6 U5 G* l) d2 y2 ~- x _8 T data_objects = [User(**data) for data in data_list]
1 V+ V' [! V6 I' L' z8 Q" d3 P& ` db.session.add_all(data_objects) W: J! {/ e6 ~; L$ @) g
db.session.commit()
) [& }6 n' w4 X- n* K return '增加成功'
; w- d7 s& G4 |% a" |% C: B4 T8 N3 W7 A3 o5 K& k# S
6 G7 c/ f+ d9 M! C
7.修改9 g# H D1 Y# \: ~) u
方法一:先查询后修改 可能会丢失数据
5 z; X; Z9 q8 L+ q7 puser = User.query.filter(User.username=="小红").first()
; J8 }- [: R' `4 z0 Cuser.email = "abc@163.com"
5 o' Z4 a, H4 _! M# x8 p1 cdb.session.commit()
: V" D- m& _2 W% q5 `! y" a: E6 ^ p" S
方法二:直接修改 推荐
* I0 X6 s' W0 J/ N+ B% Q7 OUser.query.filter(User.username == 'qqqq').update({'email': 'ABC@qq.com'})5 w6 A/ e1 C9 X2 H9 W1 o: _
db.session.commit()
- N h3 e; S0 d4 ^& g
. ]# w- W# p. b* _: f+ H#--------------------------
" U2 c- ?3 A; B0 d" G% K# 批量修改 列表套字典& k0 M' H: d1 \7 r4 ~" F% U* z% P
# 注意必须要有id 确定修改那一条1 d; ?* j- {/ M; X: s- n$ x6 T/ ]
user = User.query.filter(User.id == 1).first()
$ l3 h" a- L) U$ f- l) m; a data = [{'id': user.id, 'username': 'zzzzz', 'password': '12345678'},
/ T' u1 A4 v3 h. \ {'id': 2, 'username': 'aaa', 'password': 'zxcv'}]
8 s% o1 l2 o5 o1 k d- P, L db.session.bulk_update_mappings(User, data)
$ {; @" U4 T% j3 z db.session.commit()
6 L* C9 {5 I2 a% A0 l, B: T( b6 w1 K$ z
# d, M, Q U! x7 W
8.删除
# p+ Z, E, n' t. ]) B9 f方法一:先查询后删除 推荐
* e# A! J1 X# e/ Yuser = User.query.filter(User.username=="小红").first()
/ G( S8 V6 c& s+ _3 M o6 [7 Edb.session.delete(user), [* o9 O0 d- n* j
db.session.commit()9 y6 O2 k% \$ S3 f! r
4 u% M; w6 R! P) Z7 f. U$ Q; h
方法二:直接删除 可以删除多个+ v1 x$ i* ~' V0 u. Q5 a
user = User.query.filter(User.id == 2).delete()' O* e+ F7 F; E8 A4 l. \8 f& m
db.session.commit()
1 y2 ^, @; v% B b& g, p7 c1 `! _, r4 |* c2 J$ t9 `; d
# 假设有多个xxx 那么就可以把xxx全部删除3 R" U/ F4 p5 {
user = User.query.filter(User.username== "xxx").delete(); }; ]" Y9 ?( ~* j
db.session.commit(): j* G1 O% X i. r. |8 J5 P
cv'}]. P/ }2 v& p9 W* E! o, U9 n
db.session.bulk_update_mappings(User, data)
1 o) N4 W( W$ @2 V4 n6 T db.session.commit()( M# y$ Y3 B& W9 h+ P
4 D. ^, T) Q( U" o' o0 U+ h M& r
+ b$ R% V. Y& k+ I7 Z! ~
8.删除# e& N6 O3 I# G/ g2 m
方法一:先查询后删除 推荐: G1 c/ W$ d1 j" v
user = User.query.filter(User.username=="小红").first() l. x7 D d5 d4 @) ^' } o l* Y* _
db.session.delete(user)5 ?; M, A- z0 W* P: ^
db.session.commit()' c+ g7 d+ Z- W9 E# N( ~
! D+ p' G3 c- z i" K7 @& G) j8 C$ V' Z方法二:直接删除 可以删除多个
6 R6 `. ]" T; g7 e; A! suser = User.query.filter(User.id == 2).delete()- P3 z& S: b. u% c) Y( p- W* t
db.session.commit()
% O5 [1 L# E* r* C' t! p! H
2 x6 }4 _8 E5 R3 ~9 j" V( O1 z# 假设有多个xxx 那么就可以把xxx全部删除3 L* u# w# f1 e3 N
user = User.query.filter(User.username== "xxx").delete()
" I+ P9 t, s0 Zdb.session.commit()3 a' P9 v) G; A- o3 F
6 L" j9 M" X. r8 T2 h% p
# m$ o" ^' Z* p+ W) P# w |
|