Openstack use migrate for Database Upgrade implementation scheme detailed introduction
OpenStack with the version of the switch, the new version to add some database tables or add fields and so is the inevitable thing, how easy to do these database upgrade adaptation and management, here will be used to oslo_db in the migrate, where the M version of the heat as an example, Explain the principle of migrate management db.
We use migrate need to use the main include the following two parts: 1.versions inside the version number + database adaptation script, 2.migrate.cfg for migrate need to use the configuration file, two parts of the name is fixed.
Database upgrades using migrate are very simple, heat this provides heat-manage db_sync, db_version commands to upgrade DB and view the current DB version number, here to perform heat-manages Db_sync, Look at the migrate process.
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 code entry here, you need to pass in the engine to connect db,version for the version we need to upgrade to, there is no biography, you can see heat this is the direct use of Oslo_migrate Db_sync method, we look at the next tripartite library of this method.
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. :p Aram Engine:sqlalchemy Engine instance for a given DB//connection database:p Aram Abs_path:absolute path to migrate Repository. The absolute path to the Migrate warehouse:p Aram Version:database will upgrade/downgrade until this version.
The version number that needs to be upgraded or demoted to, if not passed, the default upgrade to the latest version if none-database will update to the latest available version. :p Aram Init_version:initial The original version number of the DB version//database, which will be upgraded starting at this initial version:p Aram Sanity_check:require s Chema sanity checking for all tables//reasonableness check "" "If version is not None:try:version = Int (version ) except Valueerror:raise exception. Dbmigrationerror (_ ("version should is an integer") current_version = Db_version (engine, Abs_path, init_version) r Epository = _find_migrate_rePO (abs_path) If Sanity_check: _db_schema_sanity_check (Engine) If version is None or version > Current_versio N: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
The code is clear and concise. As you can see, the whole process is to query the current DB version first, then declare a migrate warehouse example, do a reasonable check on db (primarily for MySQL), and then upgrade or lower it based on the incoming version and current version, and then check again, The whole migrate is finished.
The first is to query the version of the current database,
def db_version (engine, Abs_path, init_version): "" "show the current version of the R
Epository.
:p Aram Engine:sqlalchemy Engine instance for a given database:p Aram Abs_path:absolute path to migrate repository :p Aram init_version:initial Database Version "" Repository = _find_migrate_repo (abs_path) Try:return vers Ioning_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 table S:db_version_control (engine, Abs_path, version=init_version) return versioning_api.db_version (engine, repos Itory) Else:raise exception. Dbmigrationerror (_ ("" The "" the "" is not under version control, but has "" tables.) Please stamp the current version of the schema "manually.")
The first is to construct an example of a warehouse object based on the absolute path passed in, where it is more critical to initialize the following method, You can see that we mentioned earlier that migrate.cfg and versions are used here, and the names are fixed and must be migrate.cfg and 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 '% path)
log.debug (' Config:%r '% self.config.to_dict ())
This will verify that there are versions and migrate.cfg underneath the path we passed in, so our code directory structure must also be put in this. Self.config is mainly used to manage migrate.cfg configuration, self.versions is mainly used to manage how to upgrade, Repository object also contains 3 more important attributes, Latest: The latest version (the versions version number of the largest), this is 73,v Ersion_table: The database table used to record and manage the migrate version number, which is the migrate_version,id used to store the database labels we manage, here is heat, and the latter two are taken from the database.
@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 ')
Back to the previous code
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 "" The ""
is not under version control, but has "
" tables.) Please stamp the current version of the schema "
manually.")
This will be based on the database engine and just the repository instance object to get the current database version number, in fact, from the migrate itself in the datasheet to find the current version number (version_version), if the first time using migrate, An exception was thrown because the migrate_version table has not yet been established. This will look up all the data tables in the current database, and if there are other database tables, the DBMIGRATIONERROR exception will be thrown because migrate must be established before other tables can be set up to control all of the data tables. If we hadn't used the migrate mechanism before but wanted to use it in later DB control, here are 2 ideas: Manually insert the Migrate_version datasheet and configure the appropriate version or manually insert the alebic_version.
Continue to look down, if it is the first time to use migrate,
Db_version_control (engine, Abs_path, version=init_version)
will establish migrate_version, and set the appropriate initial value, that is, the incoming init_version, subsequent database upgrades and other operations can be controlled through the migrate. Once the Migrate_version table is established, it goes back to the original process, and migrate executes the upgrade () method of each version in versions until the upgrade is complete and updated according to our Db_sync incoming version number and current version number Migrate_ Version number in versions.
The advantage of using migrate is that can be very convenient to centralize records and management of each change in the database, in the subsequent upgrade process, a key to complete the corresponding adaptation operation, very convenient, and will not appear to repeat the increase of the field operations, in the development process, we just know the principle of migrate, can be very convenient to use up.
Thank you for reading, I hope to help you, thank you for your support for this site!