|
|
1.介绍
_3 |8 N8 p2 C" a8 V# [* dflask用于orm操作表,一般使用flask- sqlalchemy 操作简单
, a" C0 A8 O- f' ~) v" I7 m一般使用flask-sqlalchemy 2.5.1: x) J1 t q% e' z
https://flask-sqlalchemy.palletsprojects.com/en/2.x/
( I4 a9 F0 D& g2 I0 X& R+ \- Q1 G! Y& e9 S9 Q% L- B
# ~8 D* X" t6 w- f3 I: @1 k( U% B+ N) ~9 W, V
2.安装* y+ Q3 X3 H9 u3 R$ k
pip instal flask-sqlalchemy==2.5.1
0 ~. Z; V3 q4 [1 y. c7 Vpip install Flask-Migrate==2.6.0 # 迁移数据库使用& i+ P, p6 U# [4 I
: o% M2 W, f/ s1 g
3 j) i4 [+ |/ v) I P& L3.数据库
) A" G( b& p, [% U1.配置 连接数据库0 ~+ w4 b- r$ S. v
代表驱动
. d" j* }3 V7 I2 L3 n) ZMySQL-Python # 可以写mysqldb
! i$ V7 a P/ d: y+ P mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname>
- r( r+ i) D- i6 v8 B+ H) C. J2 c% N) h6 `1 q1 R) O
pymysql
Z p* n1 x) E mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>]
0 \( [2 A) y# j: ` S, c8 `* Y$ A- \% Z9 J. e- M
MySQL-Connector
" _3 h; D: M d3 O: l% @! [ mysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname: ?3 I6 @# v- n; w3 @5 j
, M/ A8 i5 h6 J" D F
/ Q( h- s$ ~) l% Z3 I4 P2 }
' J' O4 r$ T! J" m: x需要安装不同的扩展 注意mysqlclient的版本
$ F! M$ Y' g, V* E5 w! J可以放到配置类里面9 l/ g( l0 x# U; o- @- E0 v* [6 ?
4 y% f, X; ]& v) \, r& w
方法一 % G/ @/ l2 F- Y
SQLALCHEMY_DATABASE_URI = 'mysql://user:密码@localhost:3306/库名?charset=utf8mb4'
7 m% H& R# M- a: B3 o" e& p* w5 ]$ }; U
% I1 m4 o& D! ^2 z7 P( x方法二. u8 C$ F9 w3 o' K
DIALECT = 'mysql'& U9 E- }3 y R, M& ?
DRIVER = 'pymysql'; q# w5 `. @% _5 G& ], S. r2 {$ p
USERNAME = 'root'! K4 D& s4 `! V9 S o
PASSWORD = '****', x! o. r* i/ u& W0 k8 k
HOST = '127.0.0.1'1 r( @" k7 h* d6 s1 U [! L
PORT = '3306'
z% g! U/ P O( z; o, M: G7 {DATABASE = '数据库名'4 S+ l. v% N: L4 J$ j# n* D3 Y
% N5 C( l- m: d6 s! Y3 q3 W
SQLALCHEMY_DATABASE_URI = "{}+{}://{}:{}@{}:{}/{}?charset=utf8".format(DIALECT,DRIVER,USERNAME,PASSWORD,HOST,PORT,DATABASE)2 l4 G. A- W/ W" _
: @( U" Y* [& v$ `# v2 w& f/ `/ N# t
/ k$ S6 C# X, |; y. {
2.连接数据库
! F/ H# q$ F+ y3 E& B1 实例化SQLAlchemy对象 可放入其他文件+ g6 g3 }( p' z. l( b! f! }
from flask_sqlalchemy import SQLAlchemy2 w4 E$ m7 R' ~5 {
db = SQLAlchemy()/ W; ], P& [3 U
F3 C4 d, ^5 i/ |. M4 A2 注册db" j* @7 i0 }6 q
7 i" Y/ q( e7 u l5 `
# 初始化迁移数据库' B$ D) S; o7 a, b) p6 e& G/ M( i4 o* t
migrate = Migrate()3 T# C( y) N M& ]+ X
$ B# s6 r& }0 @+ l3 M5 \! U
def create_app() -> Flask:9 U; x) q* s! [5 w
app = Flask(__name__)0 g: D/ U3 \3 L" H6 B
app.config.from_object(Config)
1 ?! v! R0 |5 }6 M9 k # 绑定数据库0 j6 Z8 k1 k0 x8 V) L
db.init_app(app)! i u: t9 {. ?
+ h- \( T3 }1 A% j9 H# E$ }; s
# 迁移数据库
; @) {! q+ V9 L4 t/ u. {! `: D. J migrate.init_app(app, db)
5 R3 ?) R6 L, D# p- L return app( j! J) F% W( N- x, V) z+ h
2 e5 m' Z; N5 u$ c" \/ V
. N7 Z+ P% L- { o
注意命令可能无法迁移
$ x* k. G, ]3 i8 t2 f$ E. V# u0 \ B5 _& |
1. 命令行一直报 4 f- C0 w7 {" D7 ~( h$ l4 G$ L
# 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.
; s, h' }8 `1 y7 ^/ B2 u) t7 t1 a: l! _# A/ ^
这是在虚拟环境没有配置" _; s: Q# a" G$ T4 e+ @
9 T! d* Q: F$ L+ W7 F) y使用 .env 文件 来设置数据0 f! Z3 O5 {) }( X7 d' t8 J7 c6 r
# 下载 插件
- I, V, U9 o A! C5 C* ipip install python-dotenv
0 {7 N( p9 ^' Q5 a& W7 R
5 S" P: R( c9 Z# 创建app/ O g# V; J% O
def create_app() -> Flask:
1 ]8 S3 t0 d; d& P5 a# l m app = Flask(__name__)5 @5 b$ G Z) m- J9 w
# 要在最开始加载 后面才能获取到- h) V& _0 L1 I
load_dotenv(verbose=True)
% w" U' [! c! |) p6 a& r7 ?9 L; L9 H* B: o: G4 T% k
# 注册配置文件 生成/测试5 z, s' ^- V0 D+ D& y8 A
# env = str(os.environ.get("FLASK_ENV"))
3 X/ q" c) u7 U9 R) D- @ env = str(os.getenv("FLASK_ENV"))
# r6 A/ ~4 p7 V3 ]5 ` app.config.from_object(getattr(conf, env))- v. Q4 ?7 s& u0 n; S) ~
: @: z+ |5 l3 h6 n; v # 绑定数据库
5 E8 z$ v6 ~$ G1 X1 ^# t db.init_app(app)' q+ T. [" E, Q- d0 k
7 u8 H- ?+ z- I2 E% L0 _' B
# 迁移数据库
" z# ~6 h9 A; N5 ]$ i migrate.init_app(app, db)
' F! O- F4 X) w- y. x/ M2 Q return app1 F4 g8 v$ F# a( L
#-------------------------------------! o% ~/ y" a' }. k6 W+ \* K
# .env 文件
! P6 L0 x' N) s
9 ^: [# s5 q) b U1 MFLASK_APP=main.py # 自己的启动文件 默认是app.py
( R1 a. k B: G/ ]1 nFLASK_ENV=development
; k8 B" @! n8 z# g; t+ I; ]! {' l$ N7 \FLASK_DEBUG=True
6 ?5 y' W% G) `! U7 I/ O6 m+ X
1 I8 C0 O5 g' g9 }' r V6 r! N% R" V6 A; l% e
这样就可以输入命令了3 [+ K& e& _% j5 c/ w% X5 F& P: I5 a
9 ]3 \5 B+ v9 X报错误 either 'sqlalchemy_database_uri' or 'sqlalchemy_binds' must be set.
/ T* G: u9 f0 D3 |' ]没有把模型放到 view文件里面 只想要把 模型导入就好了,可以不使用
6 J2 Y. A4 J& K$ |/ Hfrom user.model import User
$ v! U3 d: e- z9 v- ?9 v+ H2 u+ n5 G8 G
2 v1 O: C0 D4 O) V
3 迁移数据库
- u; D! v+ N9 {7 H8 X# 初始化一个迁移脚本的环境,只需要执行一次。
8 p/ o' q; d% k9 X$ @: Aflask db init
; F9 [1 R3 e, _. W4 T! h* K# 将模型生成迁移文件,只要模型更改了,就需要执行一遍这个命令
" {/ z$ ]' Y; s0 b& b% N/ e8 o2 Z3 ^flask db migrate -m'迁移数据库' |3 R& \1 T' e
# 将迁移文件真正的映射到数据库中。每次运行了migrate命令后,就记得要运行这个命令。
- l1 ?3 C4 x6 @+ H* dflask db upgrade+ J! @- F: e% L0 H* `# N6 |
#-------------------------------------
; U r1 ?$ u, k' Pflask db heads 查看当前最新的迁移id9 Q' O) f8 ]" ^0 x" d+ ~( R9 ~4 o
flask db stamp heads # 更新# ?5 h" K) F3 n8 l7 k- c% H
flask db current # 查看当前迁移id
0 _4 c8 i, d: epython manage.py db history #查看历史$ {0 I5 s# h+ s' D! ^, _
python manage.py db downgrade 652a55840d #回退版本
, Q+ }3 B6 p% g+ k+ n0 z) L2 R, J; f5 J1 D- `6 f# C$ z
) `( y1 I* {9 r; [4 S" [. _4 数据库其他信息/ C; \% C! |7 u; x2 z8 v1 n! V
# 查询时会显示原始SQL语句
8 q7 q1 j4 R3 @% BSQLALCHEMY_ECHO = True
6 ]; V9 D6 p5 i. v! t# 动态追踪修改设置,如未设置只会提示警告
6 s; s. Y: J- n: o2 g( D$ V, JSQLALCHEMY_TRACK_MODIFICATIONS = False% t+ E0 y5 z1 I" w
# 数据库连接池的大小+ ]! k/ G( J, J% i8 l
SQLALCHEMY_POOL_SIZE = 10. r& ?& m4 S- O# z
# 指定数据库连接池的超时时间
+ o7 d+ H9 i" ?1 p0 ?SQLALCHEMY_POOL_TIMEOUT = 10( h% ]& ^# B' j# V( n
# 控制在连接池达到最大值后可以创建的连接数。当这些额外的 连接回收到连接池后将会被断开和抛弃。: |7 G, H+ v" [, _. d5 p: d4 V' j
SQLALCHEMY_MAX_OVERFLOW = 27 {2 E* c7 r3 ~) c* f
8 c) T/ B; M# l/ T* z3 i/ \0 N& Q8 m) \& b7 m
名字 备注
( X. M' `8 _. U( bSQLALCHEMY_DATABASE_URI 用于连接的数据库 URI 。‘mysql+pymysql://root:密码@localhost:3306/库名?charset=utf8mb4’
6 G J! x2 t. ESQLALCHEMY_BINDS 一个映射 binds 到连接 URI 的字典。更多 binds 的信息见用 Binds 操作多个数据库。2 p9 R0 K1 t4 s* v& Y. Q
SQLALCHEMY_ECHO 如果设置为Ture, SQLAlchemy 会记录所有 发给 stderr 的语句,这对调试有用。(打印sql语句)
( H$ {0 U4 m/ p0 j) l: ySQLALCHEMY_RECORD_QUERIES 可以用于显式地禁用或启用查询记录。查询记录 在调试或测试模式自动启用。更多信息见get_debug_queries()。
' B- N1 }: ]3 X( lSQLALCHEMY_NATIVE_UNICODE 可以用于显式禁用原生 unicode 支持。当使用 不合适的指定无编码的数据库默认值时,这对于 一些数据库适配器是必须的(比如 Ubuntu 上 某些版本的 PostgreSQL )。
) {# k- Y- C/ @* e6 K& k7 r6 ~9 w* SSQLALCHEMY_POOL_SIZE 数据库连接池的大小。默认是引擎默认值(通常 是 5 )
1 f2 O9 O; y! T* z5 w# ^SQLALCHEMY_POOL_TIMEOUT 设定连接池的连接超时时间。默认是 10 。' K( n9 [3 e- L2 e8 |3 u8 g
SQLALCHEMY_POOL_RECYCLE 多少秒后自动回收连接。这对 MySQL 是必要的, 它默认移除闲置多于 8 小时的连接。注意如果 使用了 MySQL , Flask-SQLALchemy 自动设定 这个值为 2 小时。; z/ @4 A3 m7 C: N# p$ h, u
4 创建表
h: M' |* c. x! mfrom core import db #这里需要引入实例化的SQLAlchemy对象
3 |- _3 @; T/ E' a. S. @3 e& n9 }+ t3 G' C$ G" _: y- L; L
class User(db.Model):3 L6 l1 Y1 j0 P2 m r5 E- v
"""用户表"""6 j/ D- u/ q$ W! ?
__tablename__ = 'user' # 创建后表名 小写( m, i! Q! V% d
# __abstract__ = True # 抽象表 不创建这个表 可以继承1 j% h- W, g, }/ [% v: e9 _
( D% ]" m+ ]7 x! G6 m6 P id = db.Column(db.Integer, primary_key=True, comment='id主键') # 必须要有
9 L0 d1 r) h6 P# x- ^& X username = db.Column(db.String(32), unique=True, comment='用户名')" b0 h7 b% f) V
password = db.Column(db.String(64), nullable=False, comment='密码')$ A8 z; Z5 Q c$ O
gender = db.Column(db.Boolean, default=0, comment='0 男 1 女')
4 G, ~ T) a" s8 V' R$ S2 e( n avatar = db.Column(db.String(125), default='http://s5p.hd-bkt.clouddn.com/default.jpg', comment='头像')9 ~1 G: t. x0 e Y
addr = db.Column(db.String(256), comment='地址')
% G2 _3 J. |1 @& C& Z! a, T6 ^ email = db.Column(db.String(125), comment='邮箱')$ ]; h% j( ~' s7 V0 x
mobile = db.Column(db.String(11), comment='电话')
( Q4 |+ l3 |* U3 C3 s$ j0 m2 d+ b login_type = db.Column(db.Integer, comment='1 电话 2 邮箱 3 用户名')
) i) v9 d& d3 e3 }5 j7 q$ @( P4 `$ N% o: a" {
def __repr__(self): # 查询的返回 和str一样
; X3 A5 ]0 H. a6 |4 I% q) R0 S: ? return f'<{self.__class__.__name__} {self.username}>'4 Z. C& e# v- `; P$ ^, v1 R
+ L9 u3 h* l% x) {' Y o+ g
- ]+ I- t( Q. u, Q: j1.字段解析" N$ V j, C! v/ ?9 M
类型名 python中类型 说明
, `% p3 U+ m F/ D9 L7 v- ?Integer int 普通整数,一般是32位. x) V* B# X) }1 g
SmallInteger int 取值范围小的整数,一般是16位7 l& P' n7 E9 r+ k/ G$ ?
BigInteger int或long 不限制精度的整数
. M- }5 C% {& q: g9 P* L3 vFloat float 浮点数1 V; x1 K" o; }( |
Numeric decimal.Decimal 普通整数,一般是32位
' B3 \5 } r. G4 [; `* fString str 变长字符串
/ _+ a. l' R9 p! }" o9 a* l) a# K9 B/ {Text str 变长字符串,对较长或不限长度的字符串做了优化6 y! l. U7 N4 S4 E, m# C
Unicode unicode 变长Unicode字符串
7 f7 A1 Q" D. H5 VUnicodeText unicode 变长Unicode字符串,对较长或不限长度的字符串做了优化
/ W4 J& C8 h& ^, a* J5 ?Boolean bool 布尔值; S! t! H7 j x; k
Date/DateTime datetime.date 时间
$ ^: m7 H1 C3 y. @- X- G' yTime datetime.datetime 日期和时间
, u7 u- h# l: b0 I0 @ |( d5 {LargeBinary str 二进制文件0 l8 {6 p# B, z7 ~) V% y- ^0 r
2.表属性
6 ]' w8 s( W6 ?+ H s选项名 说明9 p2 i {2 q4 X( ]' M+ ? A d3 r
primary_key 如果为True,代表表的主键
+ g5 E7 l" V; H! L+ junique 如果为True,代表这列不允许出现重复的值
: q: T) c& I5 p8 B9 Oindex 如果为True,为这列创建索引,提高查询效率
% n/ g! t+ d' qnullable 如果为True,允许有空值,如果为False,不允许有空值0 Y) N& B3 |* {% m3 G5 V
default 为这列定义默认值
1 Z- I! V, {* K& h& Y6 `3 r5.查询
$ {8 a, x' s$ S( `. f+ }注意只要对数据库操作就需要 db.session.commit()% `1 T) [4 b$ m# y: s) ?
2 G& E4 z/ `- |$ `: s查询方法
; m. w1 z7 P. U: q9 W- o方法 说明/ u% A$ ?& ]5 r! U+ @& X$ M3 ?( X
all() 以列表形式返回查询的所有结果! F b# u$ R6 R& O* u
first() 返回查询的第一个结果,如果未查到,返回None3 F1 A) I: ? \% N
first_or_404() 返回查询的第一个结果,如果未查到,返回404
: A; A' U% w: E( r, Q4 S' M5 Yget() 返回指定主键对应的行,如不存在,返回None' B; c2 l2 A( Z
get_or_404() 返回指定主键对应的行,如不存在,返回404
- K2 t$ i+ g4 ccount() 返回查询结果的数量
- z- D) z" o/ ^- R7 g4 ?$ ^paginate() 返回一个Paginate对象,它包含指定范围内的结果& _/ Y9 T. L4 s7 A$ \
1.普通查询1 r1 t# K2 K: J5 G) D7 i
# 查询数据条数
. f6 N7 g" O# [# W& F$ n1 jUser.query.count()8 h0 T7 M. E) X" b. o. k) C& ?3 R- K1 ?
7 G0 N" A8 U9 K# d( A1 V e6 K
# 查单条 获取不到none
( e V: p" y) T+ U6 buser = User.query.first()% u0 m/ |! [1 c" h# k8 p$ w
user = User.query.filter(User.username=="小红").first()% v6 a& `) l8 @$ o
user = db.session.query(User).filter(User.username=="小红").first()
- |9 L6 N+ _/ q5 ? @5 P# w'''1 W6 c; ` U" t! _3 T
db.session:是一种更明确的查询语法,适用于更复杂的查询场景,或者在不直接访问模型的情况下执行查询操作1 b8 h" h5 W' o$ ]
'''9 `7 a2 m! ]- k" t
0 b* q: E$ L0 Y4 z! W. ]
# 查所有
3 |" d9 G; J: I7 d$ H+ q, Guser = User.query.all()
* J0 s) \# ]+ K; H" M" Duser = User.query.filter(User.username=="小红").all()
& e' S- v0 ^4 B5 A3 muser = db.session.query(User).filter(User.username=="小红").all()
, H( j' N6 ?, R% C5 W5 s4 l
% z3 _( g; a3 j+ B- w# 只获取单条* ^0 ?% x5 [7 e8 `* F6 E# L* \
# 结果为一个时正常,多了就报错
9 a7 r% G% [* c# one_or_none() 获取不到报错- H0 |/ n$ ]( j
user=User.filter(User.username=='小红').one()
+ g, f1 h% H6 \2 Q# Z! f8 y1 Z- S
- `8 r9 z" f! a( o* m$ ^# 获取不到报错
# p" l$ C" X$ L! s, d9 [! Y! o# get里面需要参数 是id3 |( N/ k( y$ J# l: j2 ?* Z
user = User.query.get(2)
( j" k! r; i4 p, b" ?$ t# m0 B9 T- z+ s& {% [
! `# l1 Y/ b5 Z, ?
$ y1 x7 W; ?( e; f& K) C2.条件查询8 g& B3 Q# N. q& H6 o/ }6 b
# 条件查询
9 P. M: J7 j1 [' n) E2 Y user = User.query.filter(User.username=="小红",User.password=="123").first()4 \ f g. K4 T. k/ {# v
# 不等于
& Q7 h: n/ f. p& l" X$ F user = User.query.filter(User.id!=2).all()
% Z1 a% }3 z/ X# 大小于1 |4 ^" f; J; z: {" y- o
user = User.query.filter(User.id>=2).all()
2 o4 J$ D8 R2 s8 y user = User.query.filter(User.id<=2).all()3 q- ]3 K, T+ z& V8 V
* e6 q. |9 O% \* {& R$ T8 i9 W5 W#---------------------------------------- P* t" z, f9 D4 w `4 F
# 结尾为红
+ k7 T6 U& {6 OUser.query.filter(User.name.endswith("红")).all()$ e2 s9 a( U1 U4 J
User.query.filter(User.name.like("%红")).all()
& l; V' {% Q$ c4 Y# 开头为小; M/ c# @! ?# [9 A: |6 z- C& T
User.query.filter(User.name.startswith("小")).all(); e0 n/ M4 O% e! G" b+ U
User.query.filter(User.name.like("小%")).all()
% u7 e! X# t/ w5 X; P( H& N# 包含n mysql语法. v, B* W$ Q$ C. r! ]
User.query.filter(User.name.contains("n")).all()
3 Q: p* j s1 Z8 hUser.query.filter(User.name.like("%n%")).all() # 模糊查询
+ D) c% f+ f# T# F3 s- w* Q. ]
+ x' T- J$ }* v7 r4 k#-----------------------------------------
^& x3 ?5 \! X. q. J0 N1 @# 成员属于 in_. C* e/ w4 [; t7 `1 B# g
User.query.filter(User.username.in_(['aaa','bbb']).all()
z$ x. ~$ W: {5 J- O+ m#成员不属于 notin_& L0 [) `* t0 j9 {2 ]
User.query.filter(User.username.notin_(['aaa','bbb']).all(), G: v- I0 X5 E! r% r
! U; M j( V y5 ?
#----------------------------------------
# @! f1 @4 K' D" y, [7 [5 V( `from sqlalchemy import and_, or_, not_+ r+ W- b! o% k/ L2 }
# 和; T1 J7 h, ?; N
User.query.filter(User.name.startswith('a'), User.email.startswith('q')).all()
G. [4 \/ |$ ^4 C. VUser.query.filter(and_(User.name.startswith('a'), User.email.startswith('q'))).all()
4 s$ {1 K: e5 U- h" }% p# 或者
* P# E9 h" S" B' BUser.filter(or_(User.username=='qaz',User.password=='qwe123')).all()
3 d, p) P) A* {9 o) t+ Y9 K4 g' g# 非3 \- X2 A+ r% H& l
User.filter(not_(User.username=='qaz',User.password=='qwe123')).all()
$ m, y/ ~; a0 K( j% B6 F6 V/ w3 C& L8 M2 X+ `/ `
#是否空判断4 K9 C% D7 o' s. v) e9 p
User.filter(User.username==None).all() )
1 N- Z+ j+ H& o4 w0 Z9 R; KUser.filter(User.username.is_(None)).all() )5 F$ y. w* r' z- ~. l6 I/ G/ V
User.filter(User.username.isnot(None)).all() )
, l8 q0 \ D( ]/ X+ y% W0 |
( E4 z! H1 e* w% n" d/ d% k#------------------------------------------0 Q+ i' N- } X l: G, B2 K
# limit 限制返回数据条数( A, c; ?. [1 ~
# 开始条数是0
5 X. W: S) q6 a' cUser.filter(User.gender!=1).limit(2).all())4 H. ^* L; m* @* |
# 从第几条开始获取 偏移7 E8 i; L. F! H& p
User.query.offset(0).all()' U( o4 ?9 Z3 g( D7 R
# 从第2条数据到第3条 包前不报后
8 x# f W6 z1 jUser.filter(User.username!='qq').slice(2,3).all())# w! j! n9 M" q7 H- b
0 Z" v' {: w3 Q) H
# 排序 order_by 默认正序
' n8 w* B$ ~8 d User.filter(User.username!='aa').order_by(User.username).all()
1 R1 h% z4 o0 m5 g User.filter(User.username!='aa').order_by(User.id.asc()).all() 正序
" x/ K( w* D( W8 ^9 w4 E3 ~, C User.filter(User.username!='aa').order_by(User.id.desc()).all() 倒叙( w+ @: y/ _: I5 j- F( C. N
7 _# |8 T2 q7 ~$ i& t4 B5 p O* l; ~# 注意:上面的可以随意组合7 I+ f; c/ u8 `/ Q6 ^
# 其余后续补充
4 f8 N3 C. H; }- x5 z% F: i5 T: D
5 Q& u- ?1 s! e& b3.filter和filter_by8 M: ~ j; d0 J6 X4 |; m1 v
filter_by和filter都是过滤条件- v# ]7 t. L: K a; ]
filter_by 不支持比较运算符,只能用=1 \; t. }9 d/ A
( P" V* r7 K6 \0 Q' |# 返回的都是对象
- [% Y/ |- e |- Y. crows1 = User.query.filter_by(username='小红').all() J! A/ @; g1 o* d9 |7 |
rows2 = User.query..filter(User.username=='小红').all()3 T2 U/ q3 {7 O. l8 V$ y
) Z% M F0 K# k% h
# rows3 返回的是User的username属性,不是对象
7 i. M0 ]5 Q n) D8 frows3 = db.session.query(User.username).filter(User.username=='小红').all()
4 T" ~$ ~% B$ [$ g+ {# 返回的是select语句
0 s( {6 S! ]& p7 {6 @rows4 = db.session.query(User.username).filter(User.username=='小红')
& ~ c% J. t7 D. \ V7 V2 Y
8 ?6 R$ H1 w% N% H! M
* N0 n7 e; t- c( w0 i6.增加
% B6 |8 x. ^' R; q$ Z* Q1 [# 单数据增加 % N t6 E: G* z& z$ _2 `( p
user = User(username="张三",password ="123",email="123@qq.com")
4 ^6 `# |- F! F4 m, o& w" I db.session.add(user)
9 l4 g% m5 C' O. C3 c! G+ } db.session.commit()
; S5 v6 }/ C; B$ q
6 v. P$ ^6 k7 u# ~( Q1 e#-----------------------------------
1 o5 ^: P- [6 \# Y9 b+ D C# 多数据增加! T9 U+ v; v: j) M/ n- n* Y- f
# 后面两种可能会有颜色警告$ V# l; w4 e2 V- _9 e" |
方法一:使用字典列表一次性插入多条数据
3 Z+ i2 H' N8 K8 i' J& e& B8 S [, A@bl_user.route('/index')
! N) u- f% x4 ]def index():2 g) B$ b4 ~3 o" @/ i0 v! c x
data_list = [+ p) x- X2 @/ d4 x
{'username': 'value1', 'password': 'value2'},* a6 u1 e% }# J _, s/ f4 z$ f
{'username': 'value3', 'password': 'value4'},
4 S$ i" o) D8 H- L# L ]- c7 U6 S) \! e8 |/ \) n* [) e
db.session.bulk_insert_mappings(User, data_list)
' V8 Z5 O1 X+ I; t # db.session.bulk_insert_mappings(模型, 数据)+ C7 @ s# n% T' H
db.session.commit(). k3 l% s% z2 c1 n) W+ e
return '增加成功'! p, A8 D) ]5 G: s4 H! b- H
" b& U& M8 i g S/ R2 x; m# F+ ]; W方法二:将多个对象一次性保存到数据库2 M5 b* t, {, C. R9 F7 N+ E6 y0 o7 W# P6 A
@bl_user.route('/index')1 |7 N4 u; l% b* s8 k
def index():
0 t% y) e7 e* |0 D+ w0 I U7 d data_list = [
1 R+ L O- V; k9 X/ { User(username='value1', password='value2'),9 s, I- } W1 W: |8 `+ H
User(username='value3', password='value4'),
, N2 u* {2 M6 |. V" _# G- V9 _% R1 a- i ]
/ t* z8 u# u3 |2 Z3 K db.session.bulk_save_objects(data_list) M0 t9 [ D, p; o( O
db.session.commit()
: G# Z! T* y; E. _ i o return '增加成功'
- `% p1 v! [8 n% R G2 G0 B# y! e# Z c! v
方法三:0 g8 Z( c1 ]+ ]
@bl_user.route('/index')
6 r$ ?6 B! u+ p' x' `: b8 _ data_list = [
]$ a+ O3 Y' g- [" C7 f9 B {'username': 'value1', 'password': 'value2'},
) U+ C4 r7 {2 a9 h* ` {'username': 'value3', 'password': 'value4'},
H3 J. z+ T ? ~9 D& z ]& ?" V' j- H2 _( V
- B+ m2 ~: m7 E' K7 v9 V) B7 e* w
data_objects = [User(**data) for data in data_list]8 R' W+ x/ i" e& ?1 \' P g
db.session.add_all(data_objects)1 k% g# [- v; t* X0 E$ l P2 ]# p
db.session.commit()+ {" O/ q3 t- y+ {3 J
return '增加成功'
o1 u* S% a R" @* i* r
0 Q0 ~% M, _, w3 e" w' y3 f t/ }5 a O3 X1 i
7.修改) J' w9 B; H9 l
方法一:先查询后修改 可能会丢失数据
: p$ O1 D! Q+ i1 F0 N5 Xuser = User.query.filter(User.username=="小红").first()+ ], E( N! x5 d& {; c
user.email = "abc@163.com"0 G; ^/ M) G {) r `& H v
db.session.commit()9 @9 j1 S7 I# n
! D2 C* u' Q5 T/ W& G
方法二:直接修改 推荐
6 N! O$ c) X; AUser.query.filter(User.username == 'qqqq').update({'email': 'ABC@qq.com'})
' U Y j; I+ P9 ~" D+ ~, Ydb.session.commit()8 R$ Q: l6 D4 z& b- i
8 C: s( S* G6 Z. v, X
#--------------------------
: x( ?8 r" g) u( ^, @3 E5 v* s# 批量修改 列表套字典
9 R3 z# E2 z; [, j/ |* W! S# 注意必须要有id 确定修改那一条: P# k: }" T2 c% H
user = User.query.filter(User.id == 1).first()8 p: v) G1 y1 ~ T+ ?0 T
data = [{'id': user.id, 'username': 'zzzzz', 'password': '12345678'},
3 H' B* A; s( E1 _7 Y9 S c {'id': 2, 'username': 'aaa', 'password': 'zxcv'}]/ x7 g8 i$ O* L1 n X ^8 h
db.session.bulk_update_mappings(User, data)
' N* K* Q9 {/ f6 C# c* M( a db.session.commit()
, w E) \4 O( m4 A: o! B! [$ a; X, C3 p
. X1 R @* k/ m# z ]
8.删除. Z B" j+ z d
方法一:先查询后删除 推荐; R8 s/ I* N( b: i r
user = User.query.filter(User.username=="小红").first()
2 c7 n* ^2 [1 d2 t+ |5 h# zdb.session.delete(user)( j* Z: @/ o! a' _
db.session.commit()- X0 s1 J0 M9 P3 g, ]2 H3 {+ ^& G
; m8 n: _: m2 d$ `! I+ F! j, o) s方法二:直接删除 可以删除多个
) f* h1 _: K: g9 kuser = User.query.filter(User.id == 2).delete()4 S6 y9 }. Y$ E/ z
db.session.commit()7 N2 e1 K$ l" M2 I
6 v2 `; D& ^/ A' O2 _# 假设有多个xxx 那么就可以把xxx全部删除
: p, `/ ?2 V% X) W3 u& g" suser = User.query.filter(User.username== "xxx").delete()
9 z1 H i8 f/ f1 w" X9 c5 P- k2 Ndb.session.commit()
9 `3 K) @, u, G! J. v) L5 N" e: Hcv'}]
! u" Q' r3 v' ^1 s6 c N! g1 E db.session.bulk_update_mappings(User, data)
& d; o! U1 m3 q6 M, k db.session.commit()4 M, v/ ?* E9 x: s
0 t3 W8 O, I6 o2 z6 ]6 m7 R
; e7 k. ~2 ]# j
8.删除
/ [: d/ I& u6 {9 s: ]方法一:先查询后删除 推荐( z2 I) w5 U1 P% J; l9 O
user = User.query.filter(User.username=="小红").first()4 Z2 m' n/ R; L9 U
db.session.delete(user)' E; l- k5 S. i
db.session.commit()
2 K: r* ?* ?9 O: L
/ I5 u9 u8 J3 P+ x" m1 y( n方法二:直接删除 可以删除多个
4 ^4 c! b/ J+ Z6 F; @user = User.query.filter(User.id == 2).delete(). H5 Z9 V6 l0 z$ `6 A8 R& U
db.session.commit()
! {8 m6 u+ I- l/ I$ s; y6 m5 d) h+ D- ]
# 假设有多个xxx 那么就可以把xxx全部删除
0 M; L, D2 x/ Auser = User.query.filter(User.username== "xxx").delete(), k% W& q& ?6 q
db.session.commit()8 X- h* y3 b6 x; S
. |8 B( m% u: K$ P$ g% B/ `3 z5 l# `# S1 s" u6 S
|
|