flask开发restful api系列(3)--利用alembic进行数据库更改
上面两章,主要讲基本的配置,今天我们来做一个比较有趣的东西,为每个客户加一个头像图片。如果我们图片保存在自己的服务器,对于服务器要求有点高,每次下载的时候,都会阻塞网络接口,要是1000个人同时访问这张图片,会彻底报废掉整个网络。如果你跟我一样,在小公司,没有自己专业的图片服务器,又想用图片,那就跟我一样,尝试着用七牛吧。这个真的是一款很不错云产品。
首先,在model里加一个字段,
# coding:utf-8
from sqlalchemy import create_engine, ForeignKey, Column, Integer, String, Text, DateTime,\
and_, or_, SmallInteger, Float, DECIMAL, desc, asc, Table, join, event
from sqlalchemy.orm import relationship, backref, sessionmaker, scoped_session, aliased, mapper
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.hybrid import hybrid_property, hybrid_method
from sqlalchemy.orm.collections import attribute_mapped_collection
import datetime engine = create_engine("mysql://root:a12345678@127.0.0.1:3306/blog01?charset=utf8", pool_recycle=7200) Base = declarative_base() db_session = scoped_session(sessionmaker(autocommit=False,
autoflush=False,
bind=engine)) Base.query = db_session.query_property() class User(Base):
__tablename__ = 'user' id = Column('id', Integer, primary_key=True)
phone_number = Column('phone_number', String(11), index=True)
password = Column('password', String(30))
nickname = Column('nickname', String(30), index=True, nullable=True)
head_picture = Column('head_picture', String(100), default='')
register_time = Column('register_time', DateTime, index=True, default=datetime.datetime.now) if __name__ == '__main__':
Base.metadata.create_all(engine)
增加好了以后,开始整合数据库。该怎么弄呢?flask建议我们,可以使用第三方插件,flask-migrate,其他它的底层就是用的alembic,既然我们知道,就可以直接用alembic。为什么直接用alembic呢?相信大家也看出来了,我这的代码跟其他的flask用sqlalchemy不一样,很多人都直接用flask-sqlalchemy插件,但我不太喜欢。因为这个会束缚着我,为什么要用flask,就是因为它自由,想怎么改就怎么改,以后要是在这个目录下,写点脚本,直接引用即可,没有必要一定要在current_app环境下。这个只是个人喜好,喜欢用flask-sqlalchemy的可以继续使用。
首先安装alembic,由于之前安装过flask-migrate,所以直接使用apt-get install alembic就可以了。
先在blog01目录下,
alembic init my_migration
这时候,会生成my_migration目录,这时候目录如下:

这时候编辑一下alembic.ini,这是alembic的配置文件,基本只要修改一处就可以了。
sqlalchemy.url = mysql://root:a12345678@127.0.0.1:3306/blog01?charset=utf8
其实就是告诉alembic,我每次修改的时候,你去动哪个数据库
接下来就是程序,alembic的脚本是放在env.py里面,其实也只是要修改一处,就是告诉alembic,我对应的orm用的是哪个引擎。
按照正常情况下,我们只要加两行代码就够了,按照理想状况应该是这样
from model import Base
target_metadata = Base.metadata
如果我们仅仅是这样,会出现导入错误,找不到包,它不知道你要怎么引用包,所以我们要把当前目录加入到环境变量中,使之全局可用。
可是还是导入包错误,一定要把顶部的blog01也放在包里面,代价太大,不如按照标准方式,把所有文件放在app中。
import os
import sys
root = os.path.dirname(__file__) + '/..'
sys.path.append(root) from model import Base
target_metadata = Base.metadata
然后结构变成这样。

运行终端,定位到blog01目录下,
>>alembic revision --autogenerate -m 'add column head_picture'
INFO [alembic.runtime.migration] Context impl MySQLImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.autogenerate.compare] Detected added column 'user.head_picture'
Generating /home/yudahai/PycharmProjects/blog01/my_migration/versions/9a12387b186_add_column_head_picture.py ... done
生成编辑脚本,
再运行
>>alembic upgrade head
就可以了,去数据库看看吧,已经多了一个头像列了。
这边要多说一下,alembic可以增加,删除列,但对改变列有的不自动支持,需要自己稍微修改一下。下面我做一个试验,把head_picture从String(100)修改到String(120),首先我们检查一下数据库实际情况。
mysql> show create table user;
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| user | CREATE TABLE `user` (
`id` int() NOT NULL AUTO_INCREMENT,
`phone_number` varchar() DEFAULT NULL,
`password` varchar() DEFAULT NULL,
`nickname` varchar() DEFAULT NULL,
`register_time` datetime DEFAULT NULL,
`head_picture` varchar() DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `ix_user_nickname` (`nickname`),
KEY `ix_user_phone_number` (`phone_number`),
KEY `ix_user_register_time` (`register_time`)
) ENGINE=InnoDB AUTO_INCREMENT= DEFAULT CHARSET=utf8 |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
row in set (0.00 sec) mysql>
看上面的代码,head_picture是String(100),如果我们按照传统的办法,alembic是没法修改字段的,官方文档也介绍了,截取字段类型和修改字段名字,需要自己手写脚本。不要担心,其实非常非常简单。
首先,还是把model.py里面的head_picture修改为120
head_picture = Column('head_picture', String(120), default='')
然后生成脚本
$ alembic revision --autogenerate -m 'alter column head_picture string120'

会生成这个脚本文件,打开它,看代码
def upgrade():
### commands auto generated by Alembic - please adjust! ###
pass
### end Alembic commands ### def downgrade():
### commands auto generated by Alembic - please adjust! ###
pass
### end Alembic commands ###
它什么都没写,这要我们自己写的,也非常非常容易。代码如下。
from sqlalchemy.dialects import mysql def upgrade():
### commands auto generated by Alembic - please adjust! ###
op.alter_column('user', 'head_picture', sa.String(length=120), existing_type=mysql.VARCHAR(120))
### end Alembic commands ### def downgrade():
### commands auto generated by Alembic - please adjust! ###
op.alter_column('user', 'head_picture', sa.String(length=100), existing_type=mysql.VARCHAR(100))
### end Alembic commands ###
看见没有,如果对mysql稍微熟悉一点,都知道什么意思,就是直接把varchar(100)换成varchar(120),如果以后降级,再换成varchar(100)。是不是非常简单,好了,执行这个脚本吧。
$ alembic upgrade head
检查一下效果
mysql> show create table user;
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| user | CREATE TABLE `user` (
`id` int() NOT NULL AUTO_INCREMENT,
`phone_number` varchar() DEFAULT NULL,
`password` varchar() DEFAULT NULL,
`nickname` varchar() DEFAULT NULL,
`register_time` datetime DEFAULT NULL,
`head_picture` varchar() DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `ix_user_nickname` (`nickname`),
KEY `ix_user_phone_number` (`phone_number`),
KEY `ix_user_register_time` (`register_time`)
) ENGINE=InnoDB AUTO_INCREMENT= DEFAULT CHARSET=utf8 |
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
row in set (0.00 sec)
看head_picture是不是变成120了,是不是很简单?好了,这一章就介绍到这,下一章,我们介绍如何通过七牛上传图片。
flask开发restful api系列(3)--利用alembic进行数据库更改的更多相关文章
- flask开发restful api系列(8)-再谈项目结构
上一章,我们讲到,怎么用蓝图建造一个好的项目,今天我们继续深入.上一章中,我们所有的接口都写在view.py中,如果几十个,还稍微好管理一点,假如上百个,上千个,怎么找?所有接口堆在一起就显得杂乱无章 ...
- flask开发restful api系列(2)
继续上一章所讲,上一章我们最后面说道,虽然这个是很小的程序,但还有好几个要优化的地方.先复制一下老的view.py代码. # coding:utf-8 from flask import Flask, ...
- flask开发restful api系列(1)
在此之前,向大家说明的是,我们整个框架用的是flask + sqlalchemy + redis.如果没有开发过web,还是先去学习一下,这边只是介绍如果从开发web转换到开发移动端.如果flask还 ...
- flask开发restful api系列(7)-蓝图与项目结构
如果有几个原因可以让你爱上flask这个极其灵活的库,我想蓝图绝对应该算上一个,部署蓝图以后,你会发现整个程序结构非常清晰,模块之间相互不影响.蓝图对restful api的最明显效果就是版本控制:而 ...
- flask开发restful api系列(6)-配置文件
任何一个好的程序,配置文件必不可少,而且非常重要.配置文件里存储了连接数据库,redis的用户密码,不允许有任何闪失.要有灵活性,用户可以自己配置:生产环境和开发环境要分开,最好能简单的修改一个东西, ...
- flask开发restful api系列(4)--七牛图片服务
上一章我们讲到如何利用alembic来更新数据库,这章,我们讲如何通过七牛服务来存储图片. 像我们大多数公司一样,公司资金比较少,如果自己开发图片服务器,代价太大:如果我们用自己的网站服务器来保存图片 ...
- flask开发restful api系列(5)-短信验证码
我们现在开发app,注册用户的时候,不再像web一样,发送到个人邮箱了,毕竟个人邮箱在移动端填写验证都很麻烦,一般都采用短信验证码的方式.今天我们就讲讲这方面的内容. 首先,先找一个平台吧.我们公司找 ...
- flask开发restful api
flask开发restful api 如果有几个原因可以让你爱上flask这个极其灵活的库,我想蓝图绝对应该算上一个,部署蓝图以后,你会发现整个程序结构非常清晰,模块之间相互不影响.蓝图对restfu ...
- 描述怎样通过flask+redis+sqlalchemy等工具,开发restful api
flask开发restful api系列(8)-再谈项目结构 摘要: 进一步介绍flask的项目结构,使整个项目结构一目了然.阅读全文 posted @ 2016-06-06 13:54 月儿弯弯02 ...
随机推荐
- 安卓4.2原生rom状态栏显示运营商
前言:要调整状态栏布局,需反编译systemui.apk.单卡机修改status_bar.xml和signal_cluster_view.xml,双卡机修改gemini_status_bar.xml和 ...
- ural 1837 Isenbaev's Number
http://acm.timus.ru/problem.aspx?space=1&num=1837 #include <cstdio> #include <cstring&g ...
- C++定义错误码类
我们平时有这样的需求,可能是C用户的老习惯了,在底层的组件中更喜欢用返回错误码的形式来告知用户函数的调用状态,一般来说,简单用#define 一个宏来包装下返回值. #define ERR_SYSTE ...
- Css背景
index.html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> &l ...
- 深入解读ESB与SOA的关系
时至今日,SOA的概念渐渐清晰了. 有关ESB的概念,已经吵了好多年了,还是没有定论. 我个人认为,ESB本来就是抽象的概念,而且内涵丰富,在不同的场合含义不同.因此应该从不同的角度来认识. ...
- 三、Solr多核心及分词器(IK)配置
多核心的概念 多核心说白了就是多索引库.也可以理解为多个"数据库表" 说一下使用multicore的真实场景,比若说,产品搜索和会员信息搜索,不使用多核也没问题,这样带来的问题是 ...
- ArrayList 学习笔记
接口 ArrayList实现了List接口,因此可以当作一个List来使用. 此外,ArrayList还实现RandomAccess接口和Serializable,说明ArrayList支 ...
- 【回顾整理】暴走的SQL语句练习!!!
设计一个学生成绩数据库,该库包含学生,老师,课程和成绩等信息并完成后面的练习.学生:学号(SNO).姓名(SNAME).性别(SSEX).生日(SBIRTHDAY ).所属班级(SCLASS )课程: ...
- 使用OpenXml实现生成数据字典文档(beta)
最近项目在走验收流程,之前没有仔细看SOW文档,发现需要补好多份文档,其中就有数据字典,项目组不愿意花时间太多的时间弄这些文档,也不希望以后还要重复劳动力,最终决定做一个工具,方便自己生成数据字典文档 ...
- ADO.NET之使用DataGridView控件显示从服务器上获取的数据
今天回顾下ADO.NET中关于使用DataGridiew控件显示数据的相关知识 理论整理: 使用 DataGridView 控件,可以显示和编辑来自多种不同类型的数据源的表格数据. SqlDataAd ...