国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 服務器 > Web服務器 > 正文

Openstack 使用migrate進行數(shù)據(jù)庫升級實現(xiàn)方案詳細介紹

2024-09-01 13:49:30
字體:
供稿:網(wǎng)友

Openstack 使用migrate進行數(shù)據(jù)庫升級實現(xiàn)方案詳細介紹

OpenStack中隨著版本的切換,新版本加入一些數(shù)據(jù)庫表或者增加字段等是必然的事情,如何比較容易的進行這些數(shù)據(jù)庫升級的適配和管理,這里就要用到oslo_db中的migrate了,這里以為M版本的heat為例,講解一下migrate管理db的原理。

我們使用migrate需要用到的主要包含以下兩部分:1.versions里面的為版本號+數(shù)據(jù)庫適配腳本;2.migrate.cfg為migrate需要用到的配置文件,兩部分的命名是固定的。

Openstack,使用migrate進行數(shù)據(jù)庫升級,使用migrate進行數(shù)據(jù)庫升級怎么實現(xiàn),migrate,數(shù)據(jù)庫升級

使用migrate進行數(shù)據(jù)庫升級非常簡單,heat這邊提供了heat-manage db_sync, db_version的命令用來升級db以及查看當前db的版本號,這里以執(zhí)行heat-manages db_sync,看下migrate的過程。

def db_sync(engine, version=None):   path = os.path.join(os.path.abspath(os.path.dirname(__file__)),             'migrate_repo')   return oslo_migration.db_sync(engine, path, version,                  init_version=INIT_VERSION) 

heat代碼的入口在這里,需要傳入engine用來連接db,version為我們需要升級到的版本,這里沒有傳,可以看到heat這邊是直接使用oslo_migrate的db_sync方法,我們看下三方庫中的這個方法。

def db_sync(engine, abs_path, version=None, init_version=0, sanity_check=True):   """Upgrade or downgrade a database.    Function runs the upgrade() or downgrade() functions in change scripts.    :param engine:    SQLAlchemy engine instance for a given database   //連接數(shù)據(jù)庫   :param abs_path:   Absolute path to migrate repository.         //migrate倉庫的絕對路徑   :param version:   Database will upgrade/downgrade until this version. //需要升級或者降級到的版本號,如果不傳則默認升級到最新版本              If None - database will update to the latest              available version.   :param init_version: Initial database version               //數(shù)據(jù)庫的初始版本號,會以該初始版本為起點升級   :param sanity_check: Require schema sanity checking for all tables    //合理性檢查   """    if version is not None:     try:       version = int(version)     except ValueError:       raise exception.DBMigrationError(_("version should be an integer"))    current_version = db_version(engine, abs_path, init_version)   repository = _find_migrate_repo(abs_path)   if sanity_check:     _db_schema_sanity_check(engine)   if version is None or version > current_version:     migration = versioning_api.upgrade(engine, repository, version)   else:     migration = versioning_api.downgrade(engine, repository,                        version)   if sanity_check:     _db_schema_sanity_check(engine)    return migration 

代碼很清晰,簡潔。可以看到,整個過程就是先查詢下當前db的版本,然后聲明一個migrate倉庫示例,對db做合理性檢查(主要是針對mysql),然后根據(jù)傳入的version和當前的version決定是升級或者降低,最后再次檢查,整個migrate就完成了。

首先是查詢當前數(shù)據(jù)庫的版本,

def db_version(engine, abs_path, init_version):   """Show the current version of the repository.    :param engine: SQLAlchemy engine instance for a given database   :param abs_path: Absolute path to migrate repository   :param init_version: Initial database version   """   repository = _find_migrate_repo(abs_path)   try:     return versioning_api.db_version(engine, repository)   except versioning_exceptions.DatabaseNotControlledError:     meta = sqlalchemy.MetaData()     meta.reflect(bind=engine)     tables = meta.tables     if len(tables) == 0 or 'alembic_version' in tables:       db_version_control(engine, abs_path, version=init_version)       return versioning_api.db_version(engine, repository)     else:       raise exception.DBMigrationError(         _("The database is not under version control, but has "          "tables. Please stamp the current version of the schema "          "manually.")) 

首先是根據(jù)傳入的絕對路徑,構(gòu)造一個倉庫對象的示例,這里比較關鍵,初始化方法如下,可以看到我們前面提到migrate.cfg和versions就是在這里被使用的,而且名字也是固定的,必須為migrate.cfg和versions。

class Repository(pathed.Pathed):   """A project's change script repository"""    _config = 'migrate.cfg'   _versions = 'versions'    def __init__(self, path):     log.debug('Loading repository %s...' % path)     self.verify(path)     super(Repository, self).__init__(path)     self.config = cfgparse.Config(os.path.join(self.path, self._config))     self.versions = version.Collection(os.path.join(self.path,                            self._versions))     log.debug('Repository %s loaded successfully' % path)     log.debug('Config: %r' % self.config.to_dict()) 

這里會驗證我們傳入的path下面是否存在versions和migrate.cfg,因此我們的代碼目錄結(jié)構(gòu)也必須按照這個放。self.config主要是用來管理migrate.cfg的配置,self.versions主要用來管理如何升級,repository對象另外還包含3個比較重要的屬性,latest:最新的版本(versions中版本號最大的),這里是73,version_table:用來記錄和管理migrate版本號的數(shù)據(jù)庫表,這里是migrate_version,id用來存放我們管理的數(shù)據(jù)庫標示,這里是heat,后兩項都是從數(shù)據(jù)庫里面取。

@property   def latest(self):     """API to :attr:`migrate.versioning.version.Collection.latest`"""     return self.versions.latest    @property   def version_table(self):     """Returns version_table name specified in config"""     return self.config.get('db_settings', 'version_table')    @property   def id(self):     """Returns repository id specified in config"""     return self.config.get('db_settings', 'repository_id') 

回到之前的代碼

try:   return versioning_api.db_version(engine, repository) except versioning_exceptions.DatabaseNotControlledError:   meta = sqlalchemy.MetaData()   meta.reflect(bind=engine)   tables = meta.tables   if len(tables) == 0 or 'alembic_version' in tables:     db_version_control(engine, abs_path, version=init_version)     return versioning_api.db_version(engine, repository)   else:     raise exception.DBMigrationError(       _("The database is not under version control, but has "        "tables. Please stamp the current version of the schema "        "manually.")) 

這里會根據(jù)數(shù)據(jù)庫引擎和剛才的repository實例對象獲取當前數(shù)據(jù)庫的版本號,其實就是從migrate本身所在數(shù)據(jù)表中去查找當前的版本號(version_version),假如是第一次使用migrate,由于還沒有建立migrate_version表,所以引發(fā)異常。這里會去查一下當前數(shù)據(jù)庫中的所有數(shù)據(jù)表,如果已有其他數(shù)據(jù)庫表,則會引發(fā)DBMigrationError的異常,因為migrate必須在建立其他數(shù)據(jù)表之前先建立才能管控所有的數(shù)據(jù)表,假如我們之前沒有使用migrate機制但是想在后面的db控制中使用起來,這里有2個思路:手動插入migrate_version數(shù)據(jù)表并配置合適的版本或者手動插入alebic_version。

繼續(xù)往下面看,如果是第一次使用migrate,

db_version_control(engine, abs_path, version=init_version) 

會建立migrate_version,并設置合適的初始值,也就是傳入的init_version,后續(xù)的數(shù)據(jù)庫升級等操作就可以通過migrate管控起來了。migrate_version表建立起來后,就回到了最初的流程,根據(jù)我們db_sync傳入的版本號和當前的版本號,migrate會執(zhí)行versions里面每個版本的upgrade()方法直至升級完成并更新migrate_version中的版本號。

  使用migrate的好處在于,可以很方便的集中記錄和管理每次對數(shù)據(jù)庫的變動,在后續(xù)升級過程中,一鍵式完成對應的適配操作,非常方便,并且不會出現(xiàn)重復增加字段等操作,在開發(fā)過程中,我們只要知道了migrate的原理,就能很方便的使用起來了。

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 平乐县| 彰武县| 普格县| 明水县| 东乡族自治县| 锦屏县| 滕州市| 彰化市| 新民市| 西昌市| 出国| 伊吾县| 周宁县| 长沙市| 通许县| 岱山县| 绥化市| 临漳县| 海丰县| 舟山市| 九龙坡区| 遂昌县| 渝北区| 阿城市| 长治县| 孟津县| 监利县| 乐东| 海林市| 宽城| 竹北市| 呼和浩特市| 赣州市| 涡阳县| 朝阳市| 山东省| 三穗县| 垫江县| 田东县| 荔波县| 潮州市|