Openstack 通过 SQLAlchemy-ORM 访问数据库
目录
Demo
Github/JmilkFan/my-code-repertory/openstack
SQLAlchemy
SQLAlchemy 是 Python 下的一款开源软件。提供了 SQL 和对象关系映射(ORM/Object Relational Mappers)工具。使开发者可以像操作对象一般的操作数据库。
SQLAlchemy 1.1 Documentation
SQLAlchemy 1.0 Documentation
数据库的初始化
在部署 Openstack Services 的过程中需要为这些 Services 创建数据库 :
CREATE DATABASE glance;
这时我们其实仅仅是建立了数据库而已, 但是数据库中并没有表结构, 所以 Openstack Services 还提供了一条初始化(同步)数据库的指令 :
glance-manage db_sync
下面是 db_sync的代码实现方式:
# octopunch/octopunch/db/sqlalchemy/migrate_repo/versions/001_octopunch_init.py def define_tables(meta): vcenters = Table( 'vcenters', meta, Column('created_at', DateTime), Column('updated_at', DateTime), Column('deleted_at', DateTime), Column('uuid', String(length=45), primary_key=True), Column('vc_value', String(length=255)), Column('name', String(length=255)), Column('vcs_ip', String(length=255), nullable=False), Column('username', String(length=255), nullable=False), Column('password', String(length=255), nullable=False), mysql_engine='InnoDB' )
这些 Table 的定义就是我们数据库表结构的定义, 它会在我们执行数据库初始化指令的时候被用于表的创建.
数据库的操作实现
Openstack Services 对数据库的操作一般就是对数据库中的资源表的操作, 也就是对资源的操作, 所以我们先看看 Openstack 中的资源是怎么定义的.
octopunch/octopunch/api/v1/router.py
mapper.connect() 将Resource URL & Action方法 & Controller & HTTP函数 绑定到一起, 实现HTTP请求/资源/操作函数的一一对应.
from octopunch.api.v1 import vcenter class APIRouter(octopunch.api.openstack.APIRouter): ... def _setup_routes(self, mapper, ext_mgr): self.resources['versions'] = versions.create_resource() mapper.connect("versions", "/", controller=self.resources['versions'], action='show') mapper.redirect("", "/") self.resources['vcenters'] = vcenter.create_resource(ext_mgr) mapper.resource('vcenter', 'vcenters', controller=self.resources['vcenters'])
octopunch/octopunch/api/v1/vcenter.py
每一个 Resource 都会对应有一个 Controller 的类定义, 包含了对应的 Action 方法的实现.
class VcenterController(wsgi.Controller): ... def index(self, req): """Show all vcenter list.""" context = req.environ['octopunch.context'] vcenters = self.vcenter_api.vcenter_list(context) return {'vcenters':vcenters} ... def create_resource(ext_mgr): """Vcenter resource factory method.""" return wsgi.Resource(VcenterController(ext_mgr))
octopunch/octopunch/vsphere/vcenter/api.py
在 Resource 目录下的 api.py 文件中定义对数据库的操作接口.
from octopunch.db import base class API(base.Base): def vcenter_list(self, context, filters=None): """Get vcenter list. :param context: class:`RequestContext` instance :param filters: select data by filter. :type: ``dict`` :return: return a list of class:`VenterInfo` instance """ return self.db.vcenter_get_all(context, filters)
octopunch/octopunch/db/api.py
这一层 API 接口决定使用哪种 ORM 实现和数据库类型, 而且还定义了对应 vcenter/api.py 中数据库操作接口的函数. 这样做是为了支持 Openstack 数据库的异构性. 首先需要在 octopunch/octopunch/db/base.py 中使用self.db.dispose_engine()
方法让 Openstack 与数据库建立连接.
# octopunch/octopunch/db/base.py class Base(object): """DB driver is injected in the init method.""" def __init__(self, db_driver=None): # NOTE(mriedem): Without this call, multiple inheritance involving # the db Base class does not work correctly. super(Base, self).__init__() if not db_driver: db_driver = CONF.db_driver self.db = importutils.import_module(db_driver) # pylint: disable=C0103 self.db.dispose_engine()
# octopunch/octopunch/db/api.py from oslo_db import concurrency as db_concurrency ... # 指定使用 SQLALchemy, 并指定了 SQLAlchhemy 的接口路径 _BACKEND_MAPPING = {'sqlalchemy': 'octopunch.db.sqlalchemy.api'} IMPL = db_concurrency.TpoolDbapiWrapper(CONF, _BACKEND_MAPPING) ... def vcenter_get_all(context, filters=None): """Get the vcenter list. :param context: class:`RequestContext` instance :param filters: select data by filters. :type: ``dict`` :return: return a list of class:`VcenterInfo` instance. """ return IMPL.vcenter_get_all(context, filters=filters)
octopunch/octopunch/db/sqlalchemy/api.py
这里是 SQLAlchemy 操作数据库的具体实现, EG: 查询
@require_context def vcenter_get_all(context, filters=None): session = get_session() with session.begin(): vcenters_info = session.query(models.Vcenter).all() return vcenters_info
ORM 的数据库操作方式中, 很重要一部分就是 Table Mapping Class 的实现:
# octopunch/octopunch/db/sqlalchemy/models.py class Vcenter(BASE, OctopunchBase): """Represents the vcenter list.""" __tablename__ = 'vcenters' vc_value = Column(String(255)) name = Column(String(255)) vcs_ip = Column(String(255), nullable=False) username = Column(String(255), nullable=False) password = Column(String(255), nullable=False) datacenters = relationship('Datacenter', backref='vcenters', foreign_keys='Datacenter.vcenter_uuid', primaryjoin='Vcenter.uuid ==' 'Datacenter.vcenter_uuid')
将上述的 Table 定义映射为 Class之后, 我们就可以通过对 Class instance 的操作来实现对数据库 Table 的操作.
数据库的操作请求
在调试的时候我们可以在客户端通过 curl 指令来发送 HTTP 请求, 一般来说对每个 Resource 的 HTTP 请求都具有下面 5 种类型, 每一种类型都应该在 api/v1/resourceName.py 文件下(针对本文而言, 其实可以有多种实现方式)有相应的 Action 实现函数, 当然我们还可以自定义更多的实现方法.
全部查询
GET <==> show
curl -i 'http://<Service_host_ip>:<service_port>/v1/<project_id>/<ResourceUrl>' -X GET -H "Acceptn" -H "X: admin" -H "X-Auth-Token: <token_id>"
单个查询
GET <==> index
curl -i 'http://<Service_host_ip>:<service_port>/v1/<project_id>/<ResourceUrl>/<ResourceID>' -X GET -H "Acceptn" -H "X-Auth-Project-Id: admin" -H "X-Auth-Token: <token_id>"
创建
POST <==> create
curl -i 'http://<Service_host_ip>:<service_port>/v1/<project_id>/<ResourceUrl>' -X POST -H "Content-Type: application/json" -H "X-Auth-Project-Id: admin" -H "X-Auth-Token: <token_id>" -d '<body_content_dict>'
更新
PUT <==> update
curl -i 'http://<Service_host_ip>:<service_port>/v1/<project_id>/<ResourceUrl>/<ResourceID>' -X PUT -H "Content-Type: application/json" -H "X-Auth-Project-Id: admin" -H "X-Auth-Token: <token_id>" -d '<body_content_dict>'
删除
DELETE <==> delete
curl -i 'http://<Service_host_ip>:<service_port>/v1/<project_id>/<ResourceUrl>/<ResourceID>' -X DELETE -H "Acceptn" -H "X-Auth-Project-Id: admin" -H "X-Auth-Token: <token_id>"

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
创建第二个 local network - 每天5分钟玩转 OpenStack(84)
GUI 中有两个地方可以创建 network: 1. Project -> Network -> Networks 这是普通用户在自己的 tenant 中创建 network 的地方。 2. Admin -> Networks这是 admin 创建 network 的地方。 前面我们已经用第一种方式创建了 "first_local_net",本节将以第二种方式创建 local network "second_local_net"。 菜单路径为 Admin -> Networks,此菜单只有 admin 用户才能够访问。 点击 “Create Network” 按钮。 显示创建页面。 可以看到几个与普通用户创建 network 不同的地方: 可以选择该 network 属于哪个 Project(租户)。 可以选择 network type。 可以指定 network 是否与其他 Project 共享。 可以指定是否为 external network。 可见,这种方式赋予 admin 用户创建 network 更大的灵活性,后面我们都将采用这种方式创建 netwo...
- 下一篇
阿里云容器服务--自定义路由和负载均衡策略
简单示例 让我们先从一个简单的例子开始,我们会部署一个acs/proxy容器,容器前面配置一个slb实例,让大家可以访问,同时在后端挂上一个nginx,这里我们只展示nginx的首页。 compose模板如下所示: lb: image: registry.aliyuncs.com/acs/proxy:0.5 ports: - '80:80' restart: always labels: # addon 使得proxy镜像有订阅注册中心的能力,动态加载服务的路由 aliyun.custom_addon: "proxy" # 每台vm 部署一个该镜像的容器 aliyun.global: "true"
相关文章
文章评论
共有0条评论来说两句吧...