sqlalchemy is important(1)

来源:互联网 发布:单链表实现java 编辑:程序博客网 时间:2024/06/06 03:06

如果亲手配置过openstack,不论是standalone的还是分布式的,肯定对类似这样一句有深刻的印象:

connection=mysql://xxx/glance

xxx是user:passwd@url的形式,当然了大部分情况下使用的都是mysql,也有postgresql,sqlite的,但是我知道最多的还是mysql

sqlalchemy是什么?简单的说用来做ORM,或者说做数据的持久化,为什么需要sqlalchemy?两个主要原因:

第一:封装,并不是所有人都擅长写sql语句,也不是所有人都关心具体的实现,怎么select,怎么insert,update,使用sqlalchemy封装了这一层,使得开发人员可以更加

关注上层的逻辑;

第二:还是封装,使用sqlalchemy可以配不同的backend,就像上面说的有sqlite,mysql,postgresql等,不用在刻意关注不同backend的差异,同样的将注意力放在逻辑上。


sqlalchemy在哪里:

>>> print sqlalchemy.__path__
['/usr/lib64/python2.7/site-packages/sqlalchemy'],注意这里是lib64,libvirt的库也在这个目录下

同时,我们能在source code中发现”两个“sqlalchemy,一个是上面说到的,另一个在oslo.db中(针对openstack使用做了一些小的封装)


ok,在配置openstack的时候,都有创建数据库的印象,类似于:

# mysql -u root -p
mysql> CREATE DATABASE nova;
mysql> GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'localhost' \
IDENTIFIED BY 'openstack';
mysql> GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'%' \
IDENTIFIED BY 'openstack';

这一步创建了数据库,有数据库才有数据表,那么创建数据表是在哪一步呢?

nova-manage db_sync

btw: 其他的模块,比如keystone,neutron,都是类似的情况,关键在于

xx-manage db_sync发生了什么:

在CentOS下查看脚本/usr/bin/nova-manage

from nova.cmd.manage import main
if __name__ == "__main__":
    sys.exit(main())

执行DbCommands:   

@args('--version', metavar='<version>', help='Database version')
    def sync(self, version=None):
        """Sync the database up to the most recent version."""
        return migration.db_sync(version) #即nova/db/sqlalchemy/migrations.py中的db_sync方法

trace一下这个函数,一般的version为None

current_version = db_version()

执行_find_migrate_repo,对应的path为nova/db/sqlalchemy/migrate_repo目录,返回repo为:_REPOSITORY =Repository(path)

记住此处的Repository类,

current_version = versioning_api.db_version(get_engine(), repository) #为migrate/vesioning/api.py中的db_version方法

其中get_engine()将通过oslo/db/sqlalchemy/中:

EngineFacade.from_config(CONF).get_engine执行:

 engine = sqlalchemy.create_engine(url, **engine_args) 得到engine

repository就是刚才得到的Repository

version从哪里来的呢,trace代码,version从version_table而来,而在nova/db/sqlalchemy/migrate_repo/migrate.cfg中配置:

repository_id=nova
version_table=migrate_version

于是进入nova数据库中:

MariaDB [nova]> select * from migrate_version;
+---------------+------------------------------------------------------------------+---------+
| repository_id | repository_path                                                  | version |
+---------------+------------------------------------------------------------------+---------+
| nova          | /usr/lib/python2.7/site-packages/nova/db/sqlalchemy/migrate_repo |     254 |
+---------------+------------------------------------------------------------------+---------+
得出version为254

    repository = _find_migrate_repo()
    if version is None or version > current_version:
        return versioning_api.upgrade(get_engine(), repository, version) #可以trace一下,从当前version到新versin的升级过程
    else:
        return versioning_api.downgrade(get_engine(), repository,
                                        version)

问题是这样看起来像是从某一个版本向上upgrade,但是一开始的时候migrate_repo中的version是怎么写到数据库的呢?

migrate/versioning/api.py中的version_control方法的doc中有一段:

 By default, the database begins at version 0 and is assumed to be
    empty.  If the database is not empty, you may specify a version at
    which to begin instead. No attempt is made to verify this
    version's correctness - the database schema is expected to be
    identical to what it would be if the database were created from
    scratch.

初始化,第一次执行db sync时,select * from migrate_version;得到的version是0,会执行migrate_repo中的.py文件的upgrade来创建表,
自己添加之后运行db_sync则会将新添加或修改的表同步到数据库中。


openstack的数据库部分有很多需要改进的地方,数据库是openstack极其重要的一部分,由于sqlalchemy的出现,一般地你感觉不到数据库的存在,

然而这让数据库更加重要,数据的同步,更新,持久化必然是cloud中的重要核心。



0 0
原创粉丝点击