数据库-SHELL

数据库按照一定规则保存程序数据,程序再发起查询去取回所需的数据。分为文档数据库(NoSQL)键值数据库(SQL),具体可去百度百科看介绍,这类不再赘述。Web程序最常用是基于关系模型的数据库

数据库框架

大多数数据库引擎都有对应的python包,除此之外还可以选择数据库抽象层和SQLAlchemy和MongoEngine。
这里采用Flask-SQLAlchemy管理数据库。接下来用的数据是MySQL,安装方法见[随笔]
(http://www.jianshu.com/p/9b48ae42e92a)


然而我用的flask搭建python3.5平台,实际操作过程中出现提示未导入mysqldb(mysql-python)库,目前只支持python2.7。所以网站改用python自带轻量级SQLite。


hello.py:配置数据库

from flask.ext.sqlalchemy import SQLAlchemy
basedir = os.path.abspath(os.path.dirname(__file__))
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///'+os.path.join(basedir,'data.sqlite')
 #数据库位置
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] =True 
#每次请求结束后自动提交数据库中的变动
db = SQLAlchemy(app)

flask quickstart定义数据位置输入的是

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:tmp/test.db'

差异在这里用basedir获取该文件所在路径,所以数据库与hello.py同级

hello.py:定义Role和User模型

class NameFome(Form):
    name = StringField('who are you', validators=[Required()])
    submit = SubmitField('Submit')

class Role(db.Model):
    __tablename__ = 'roles' #定义数据库中使用的表名
    #模型的属性,定义为db.Column的实例
    id = db.Column(db.Integer,primary_key=True)
    name = db.Column(db.String(64), unique=True)
    #可选,定义__repr__方法,返回一个具有可读性的字符串表示模型
    def __repr__(self):
        return '' %self.name
        
class User(db.Model):
    __table__name = 'users'
    id = db.Column(db.Integer,primary_key=True)
    username = db.Column(db.String(64),unique=True, index=True)
    
    def __repr__(self):
        return '' %self.username

hello.py:关系

class Role(db.Model):
#...
    uers = db.relationship('User',backref='role')

class User(db.Model):
  #...
    role_id = db.Column(db.Integer,db.ForeignKey('roles.id'))

所谓关系就是Role和User之间建立了链接。关系用users表中的外键(ForeignKey)连接了两行。

添加到users表中role_id被定义为外键,传给db.ForeignKey()的参数表明这列的值是roles表中的id值
添加到Role模型中的users属性代表这个关系的面向对象视角。db.relationship()第一个参数表明这个关系的另一端是哪个模型。backref参数向User模型中添加一个role属性,这一属性可替代role_id访问Role模型,此时获取的是模型对象而不是外键的值

上面这段话太复杂了,不懂多看几遍,下面介绍一下常用的数据库操作。

预先操作:

python hello.py shell
  1. 创建表
    首先,让flask-sqlalchemy根据模型类参加数据库.
    from hello import db
    db.create_all()
  2. insert
    from hello import Role, User
    admin_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=mod_role)
    user_david = User(username='David',role=user_role)

模型的构造函数(Role())接受的参数(name,username)是使用关键字参数指定的模型属性初始值

通过会话(session)管理数据库所做的改动。在flask_sqlalchemy中,会话由db.session表示
添加
多个添加

 db.session.add_all([admin_role, mod_role,user_role,user_john,user_susan, user_david])

单个添加

db.session.add(xxx)

提交

db.session.commit()

回滚

db.session.rollback()

始终保证在会话中提交改动,这样可以避免因部分更新导致数据的不一致性。

3.修改行

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

4.删除行

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

5.查询行

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

一旦退出shell会话,这些例子中创建的对象不会以python对象的形式存在,而是作为各自数据库中的行。重新打开shell会话,需要从数据库中读取行,再重新创建python对象。
如果每次启动shell会话都要导入数据库实例和模型,那么真的要难过死了。这个可以通过为shell增加一个上下文解决

from flask.ext.script import Manager, Shell
def make_shell_context():
    return dict(app=app,db=db,User=User,Role=Role)
manager.add_command("shell",Shell(make_context=make_shell_context))

你可能感兴趣的:(数据库-SHELL)