配置
具体配置见文档
方案是flask+SQLAlchemy(flask_SQLAlchemy插件)+SQLite
数据库文件时存储在app.db,即本地文件,SQLite无需像MySQL等启动服务
参考这个项目的建表方式,我建立了两张表
models.py代码如下
from app import db
from datetime import datetime
class EpochInfo(db.Model):
__tablename__ = "epochinfo" #表的名字
id = db.Column(db.Integer, primary_key=True)
var_epoch = db.Column(db.Integer, index=True)
epoch = db.Column(db.Integer, index=True)
posts = db.relationship('Post', backref='result', lazy='dynamic') #backref在调用时可以使用虚拟字段result来调用其作者,而不必通过用户ID来处理,如在使用的时候使用e=EpochInfo.query.get(3) 3指id, p = Post(body="bilibili", result=e) ;lazy决定SQLAlchemy什么时候从数据库中加载数据(dynamic表示访问属性是,并没有在内存中加载数据而是返回一个query对象,需要执行相应方法,如.all()才可以获取)
def __repr__(self):
return '<epochDB {}>'.format(self.var_epoch)
class Post(db.Model):
__tablename__ = "post" #表的名字
id = db.Column(db.Integer, primary_key=True)
body = db.Column(db.Text)
timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow) #timestamp有一个默认值
epoch_id = db.Column(db.Integer, db.ForeignKey('epochinfo.id'))
def __repr__(self):
return '<Post {}>'.format(self.body)
- EpochInfo
- id 自动生成,作为主键,不用在意,使用backref可以使用虚拟字段
- var_epoch 主要存储每一轮的epoch编号
- epoch 存储的是从表格获取的epoch数据,可能多轮之间的epoch会有重复,所以这里使用id可以加以区分,在 posts打印的时候认准同一个id对应的epoch就可以了
- posts 主要是一个post表项和EpochInfo表项之间关系的一个说明
- Post
- id 自动生成,主键
- body 存储的主要是关于具体内容的信息
- timestamp 时间戳自动初始化,也不用关心
- epoch_id 为一个外键,对应的是EpochInfo表中的id
如何操作
步骤
步骤上来讲,其实类似git,首先写好要加入数据库的内容,然后add,然后commit提交更改
更改模型(models.py中的信息,比如添加新表),需要使用迁移flask db migrate
然后flask db upgrade
,回滚使用flask db downgrade
对于具体表的读写
进入交互式环境,导入实例和模型
from app import db
from app.models import EpochInfo, Post #EpochInfo是epoch相关信息,post是运行结果信息
新建Epoch信息
e = EpochInfo(var_epoch=0, epoch=30)
db.session.add(e)
db.session.commit()
查询Epoch信息
#查询所有epoch信息
epoches = EpochInfo.query.all()
#查看当前返回的信息,可以看到存了多少项
epoches
#查看epoches中具体每一项
for e in epoches:
print(e.id, e.var_epoch)
模型都有query
属性,最基本查询就是返回所有的元素,适当命名为all()
。添加用户是,id字段依次自动设置为1 2 3...
知道id,可以直接下面这种方式获取用户实例
e = EpochInfo.query.get(1) #这里的1是id
添加一条post
e = EpochInfo.query.get(1)
p = Post(body='my first post!', result=e) #这里的result就是用的虚拟字段,因为e已经获取了id信息了,可以直接用e来引用id为1的记录
db.session.add(p)
db.session.commit()
其他查询案例
>>> # get all posts written by a user
>>> u = User.query.get(1)
>>> u
<User john>
>>> posts = u.posts.all()
>>> posts
[<Post my first post!>]
>>> # same, but with a user that has no posts
>>> u = User.query.get(2)
>>> u
<User susan>
>>> u.posts.all()
[]
>>> # print post author and body for all posts
>>> posts = Post.query.all()
>>> for p in posts:
... print(p.id, p.author.username, p.body)
...
1 john my first post!
# get all users in reverse alphabetical order
>>> User.query.order_by(User.username.desc()).all()
[<User susan>, <User john>]
删除记录(可以在每次试验结束后,删除之前的所有记录
>>> users = User.query.all()
>>> for u in users:
... db.session.delete(u)
...
>>> posts = Post.query.all()
>>> for p in posts:
... db.session.delete(p)
...
>>> db.session.commit()
日积月累,水滴石穿