flask-sqlalchemy操作及一些报错的解决方法

1,104 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情

数据库的连接
app.config['SQLALCHEMY_DATABASE_URI']='mysql://flaskyadmin:123456@192.168.3.4/flasky'

创建一个数据库用户

create user '用户名'@'地址' identified by '密码'

常用数据库url格式
Mysqlmysql://username:password@hostname/database
SQLitesqlite:///c:/absolute/path/database
定义一个数据库模型

这里可以设置为False,否则运行时会有警告

设置这一项是每次请求结束都会自动提交数据库中的变动

app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=False
from flask import Flask
from flask_sqlalchemy import SQLALchemy
​
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI']='mysql://flaskyadmin:123456@192.168.3.4/flasky'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=False
​
db=SQLAlchemy(app)
​
​
class Role(db.Model):
    __tablename__ = 'roles'  #表名称
    id = db.Column(db.Integer,primary_key=True) #Int类型,设置为主键
    name = db.Column(db.String(64),unique=True) #字符串类型,unique列不允许出现重复值
​
    def __repr__(self):
        return 'Roles %r' %self.name
​
class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer,primary_key=True) #Int类型,设置为主键
    #字符串类型,unique列不允许出现重复值,index为列创建引索
    username = db.Column(db.String(64),unique=True,index=True) 
​
    def __repr__(self):
        return '<User %r>' %self.username
报错记录

报错内容:

MySQLdb._exceptions.OperationalError: (1045, "Access denied for user 'flaskyadmin'@'192.168.3.9' (using password: YES)")

原因是数据库权限问题,所有要到数据库上对其进行授权

命令如下:

grant all privileges on *.* to 'flaskyadmin'@'%' identified by '123456'

插入行
admin_role=Role(name='Admin')
user_role=Role(name='User')
user_test1=User(username='test1',role=admin_role)
user_test2=User(username='test2',role=user_role)
​
#创建的数据此时并不在数据库中,而是存在python中,所以要通过session提交到数据库中
db.session.add(admin_role)
db.session.add(user_role)
db.session.add(user_test1)
........
#也可以用另一种方法
db.session.add_all([admin_role,user_role,user_test1,user_test2])
db.session.commit()#提交会话#数据库db.session()会话与数据库事务为同一个意思

如果在写入会话的时候发生错误,整个会话失败,同时也会有导致数据库内容与会话不一致,会话db.session.commit()失败

这时可以对数据库会话进行回滚

db.session.rollback()

修改行

可以使用add()方法对之前定义模型中的内容进行修改

admin_role.name='Administrator'
db.session.add(admin_role)
db.commit()
查询

Flask-SQLALchemy为每个模型都提供query,使用all()方法返回对应表的所有记录

Role.query.all()

除了all()方法全部显示外

还可以使用过滤器配置query对象

User.query.filter_by(role=user_role).all()

如果想看查询命令的原生SQL语句只需要将其转换为str()就行,其中filter_by为过滤器

str(User.query.filter_by(role=user_role))

如果退出shell会话,前面创建的对象(例如user_role,admin_role之类的)都不会以Python对象的形式存在,但数据库的表中仍有对应的行。

这时候就需要将数据重新导入对象中,first()方法只返回第一个结果

user_role=Role.query.filter_by(name='User').first()

过滤器:

filter_by() :把等值过滤器加到原查询上,返回一个新查询

order_by():把指定条件对原查询结果进行排序,返回一个新的查询

执行方法:

all()以列表的形式返回查询的所有结果

first()返回查询的第一个结果,如果没有,返回None

get_or_404()返回指定主键对应的行,如果没有,终止请求,返回404错误响应

get()返回指定主键对应的行,如果没有对应的行,返回None

报错

AttributeError: 'InstrumentedList' object has no attribute 'order_by'

解决方法:

重进进入flask shell

然后将数据重新导入对象中,再使用order_by()则可以成功