数据库及ORM
alembic 版本管理
- 要使用alembic 首先要安装alembic 管理工具, 使用pip工具进行安装。会自动安装三个依赖包
pip install alembic
- 执行初始化会生成包括alembic.ini文件在内的一些文件。
其中:
alembic.ini 提供的是基本配置, 比如数据库连接的配置
env.py 每次执行alembic都会加载该模块,配置了SqlAlembic Models的连接
version 该目录下存放是在将来生成的版本
script.py.mako 迁移脚脚本生成模板在环境workspace中新建一个文件件, 然后在文件夹内执行:mkdir alembic_study cd alembic_study alembic init <the alembic_dic> ex: alembic init alembic
- 修改数据库连接,在此之前需要在环境上安装好数据库,并创建出自己的表
mysql -u root -p create database test_alembic; show databases;
例如现在是的数据库使用:test_alembic
则在alembic.ini中配置数据库连接, 用户名和密码根据实际情况进行定义。 - 在代码中创建Modules目录和models.py文件,如下所示:
models.py文件内容拷贝网上他人写好的模板即可from sqlalchemy import Column, Integer, String, ForeignKey, Date, Table, Text from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship Base = declarative_base() useridToRoleid = Table('useridToRoleid', Base.metadata, Column('userid', Integer, ForeignKey('users.id')), Column('roleid', Integer, ForeignKey('roles.id')), ) roleidToIdentityid = Table('roleidToIdentityid', Base.metadata, Column('roleid', Integer, ForeignKey('roles.id')), Column('identityid', Integer, ForeignKey('identities.id')), ) articleidToTagid = Table('articleidToTagid', Base.metadata, Column('articleid', Integer, ForeignKey('articles.id')), Column('tagid', Integer, ForeignKey('tags.id')), ) class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True) username = Column(String(32), nullable=False, unique=True) password = Column(String(32), nullable=False) email = Column(String(32), nullable=False, unique=True) roles = relationship('Role', secondary=useridToRoleid, backref='users') def __repr__(self): return "<%s users.username: %s>" % (self.id, self.username) class Role(Base): __tablename__ = 'roles' id = Column(Integer, primary_key=True) name = Column(String(16), nullable=False) identity = relationship('Identity', secondary=roleidToIdentityid, backref='roles') def __repr__(self): return "<%s roles.name: %s>" % (self.id, self.name) class Identity(Base): __tablename__ = 'identities' id = Column(Integer, primary_key=True) name = Column(String(16)) def __repr__(self): return "<%s identities.name: %s>" % (self.id, self.name) class Category(Base): __tablename__ = "categories" id = Column(Integer, primary_key=True) name = Column(String(16), nullable=False) title = relationship('Article', backref='category') def __repr__(self): return "<%s categories.name: %s" % (self.id, self.name) class Tag(Base): __tablename__ = "tags" id = Column(Integer, primary_key=True) name = Column(String(16)) def __repr__(self): return "<%s categories.name: %s" % (self.id, self.name) class Article(Base): __tablename__ = "articles" id = Column(Integer, primary_key=True) title = Column(String(50)) description = Column(String(300)) content = Column(Text) click_count = Column(Integer, default=0) category_id = Column(Integer, ForeignKey('categories.id')) tags = relationship('Tag', secondary=articleidToTagid, backref='articles') def __repr__(self): return "<%s categories.name: %s" % (self.id, self.title)
- 修改env.py配置文件,将target_metdata =None 替换掉
这样alembic就能获取自己项目中的models中定义的信息
- 在alembic.ini文件所在的路径先执行创建数据库版本的文件, alembic reversion -m "注释"
生成如下所示:versions目录下生成一个文件,格式是:版本号_注释.py文件alembic revision --autogenerate -m "init the db"
- 变更数据库,如果修改了models.py中的表结构, 比如增加了新的字段
在user表中新增了一个telphone的字段。要经过两个步骤就可再生成一个version文件alembic upgrade head #每次要创建新的版本,需要执行数据库升级到新版本的命令,才能继续更新版本 alembic revision --autogenerate -m "add telphont for role"
- head 指的是最新版本,base指的是最初版本, 需要对数据库升级使用upgrade, 降级则使用downgrade
- 将数据库降级
降级到最初的版本alembic downgrade base
将数据库降级到执行版本: alembic downgrade 版本号
alembic downgrade 1234567890
- 查询当前版本号
在数据库中有一个alembic_version的字段,表示的是最后一个版本的版本号 - versions中的版本文件控制升级和降级
这是第一个version文件,所有只有revsion, 表示当前版本的版本号,没有父版本down_revison
对于刚才生成的第二个文件
这个version文件有父文件:down_revision, 即它是从哪个version文件升级过来的,指向的是它上一级的文件。
执行升级和降级就是通过revision和down_revision文件来实现的 - versions 内容
upgrade()表示该版本在升级的时候添加的内容,downgrade()表示该版本在回退时候要删除的内容
版本升级与回退问题
- 不同分支出现version文件反合的问题