python Flask-SQLAlchemy操作数据库

来源:互联网 发布:linux使用ss科学上网 编辑:程序博客网 时间:2024/04/29 22:18

数据库URL必须保存到Flask配置对象的SQLALCHEMY_DATABASE_URI键中。将SQLALCHEMY_COMMIT_ON_TEARDOWN键,将其设为True时,每次请求结束后都会自动提交数据库中的变动。
简单的配置SQLite数据库

from flask_sqlalchemy import SQLAlchemybasedir = os.path.abspath(os.path.dirname(__file__))app = Flask(__name__)app.config['SECRET_KEY'] = 'hard to guess string'app.config['SQLALCHEMY_DATABASE_URI'] =\    'sqlite:///' + os.path.join(basedir, 'data.sqlite')app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True

定义模型

class Role(db.Model):    __tablename__ = 'roles'    id = db.Column(db.Integer, primary_key=True)    name = db.Column(db.String(64), unique=True)    users = db.relationship('User', backref='role', lazy='dynamic')    def __repr__(self):        return '<Role %r>' % self.nameclass User(db.Model):    __tablename__ = 'users'    id = db.Column(db.Integer, primary_key=True)    username = db.Column(db.String(64), unique=True, index=True)    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))    def __repr__(self):        return '<User %r>' % self.username

tablename定义在数据库中使用的表名。添加到User模型中的role_id列被定义为外键,就是这个外键建立了关系。传给db.ForeignKey()的参数‘role.id’表明,这列的值是roles表中的行的id值。
添加到Role模型中的users属性代表这个关系的面向对象视角。对于一个Role类的实例,其users属性将返回与角色相关联的用户组成的列表。db.relationship()的第一个参数表明这个关系的另一端是那个模型。
db.relationship()中的backref参数向User模型中添加一个role模型,从而定义反向关系。这一属性可替代role_id访问Role模型,此时获取的是模型对象,而不是外键的值。
db.relationship()表示一对一关系时,把uselist设置为False,把多变成一

接下来在flask-script中操作数据库

python hello.py shell

创建表

from hello import dbdb.create_all()db.drop_all()db.create_all()

插入行

from hello import Role, Useradmin_role = Role(name='Admin')mod_role = Role(name='Moderator')user_role = Role(name='User')user_john = User(username='john', role=admin_role)user_susan = User(username='susan', role=user_role)user_david = User(username='david', role=user_role)db.session.add(admin_role)或者可以批量添加到会话中db.session.add_all([admin_role,mod_role,...,user_david])提交给数据库db.session.commit()

修改行

admin_role.name = 'test'db.session.add(admin_role)db.session.commit()

删除行

db.session.delete(mod_role)db.session.commit()

查询行

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

常用的SQLALchemy查询过滤器

过滤器 说明 filter() 把过滤器添加到原查询上 filter_by() 把等值过滤器添加到原查询上 limit() 限制原查询返回的结果数量 offset() 偏移原始查询返回的结果 order_by() 根据指定条件对原查询进行排序 group_by() 根据指定条件对原查询结果进行分组

users = db.relationship('User', backref='role', lazy='dynamic') 加入了lazy=’dynamic’参数,从而禁止自动执行查询,user_role.users会返回一个尚未执行的查询,因此可以在其上添加过滤器
user_role.users.order_by(User.username).all()

Flask-SQLAlchemy要求每个模型都要定义主键,这一列经常命名为id

最常用的SQLALCHEMY列选项

选项名 说明 primary_key 主键 unique 是否允许重复值 index 设为True,为这一 列建立索引 nullable 设为True,允许使用空 default 默认值

集成Python Shell
每次启动Shell会话都要导入数据库实例和模型,可以配置让Flask-script的shell命令自动导入特定的对象

from flask_script import Shelldef make_shell_context():    return dict(app=app, db=db, User=User, Role=Role)manager.add_command("shell", Shell(make_context=make_shell_context))再次执行 python hello.py shell>>> db<SQLAlchemy engine='sqlite:///C:\\Users\\yuchuan\\PycharmProjects\\flasky\\data.sqlite'>>>> app<Flask 'hello'>>>> User<class '__main__.User'>

在视图函数中操作数据库

@app.route('/', methods=['GET', 'POST'])def index():    form = NameForm()    if form.validate_on_submit():        #从数据库中查询是否存在        user = User.query.filter_by(username=form.name.data).first()        if user is None:            user = User(username=form.name.data)            db.session.add(user)            session['known']=False        else:            session['known']=True        session['name']=form.name.data        form.name.data = ''        return redirect(url_for('index'))    return render_template('index.html', form=form, known=session.get('known', False), name=session.get('name'))

index.html

{% block page_content %}<div class="page-header">    <h1>Hello, {% if name %}{{ name }}{% else %}Stranger{% endif %}!</h1>{% if not known %}<p>Pleased to meet you !</p>{% else %}<p>Happy to see you again!</p>{% endif %}</div>{{ wtf.quick_form(form) }}{% endblock %}

本文参考《Flask Web开发-基于Python的Web应用开发实战》

0 0
原创粉丝点击