【OpenStack】SqlAlchemy

本文介绍了SqlAlchemy在OpenStack中的应用,包括SqlAlchemy的两大组成部分:ORM和SQL Expression Language,以及数据库操作的基本流程,如指定数据库引擎、定义数据类和增删改查操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

声明:
本博客内容来源网上,忘了是从哪里看到的,如果原作者看到,请联系我附上链接,同时对您的付出表示感谢!
新浪微博:@孔令贤HW;
博客地址:http://blog.youkuaiyun.com/lynn_kong
内容系本人学习、研究和总结,如有雷同,实属荣幸!

什么是SqlAlchemy?

SqlAlchemy是一个开源的Python组件,提供数据库抽象的功能,屏蔽不同数据库的差异,为用户提供一致的Python对象操作,结构如下:

对用户而言,SqlAlchemy有两个重要的组成部分,其一,ORM(Object Relational Map,对象关系映射),负责将数据库中的数据(数据表)与Python的对象链接在一起,以操作对象的形式来完成数据操作;其二,SQL Expression Language SQL解释语言,可以将命令转化为底层数据库支持的操作,是一个独立组件,和ORM一同工作的时候负责将对象操作转化为底层数据库的相关命令。也可以单独使用,获得较高的执行效率。

数据库操作流程

1. 指定数据库引擎(Engine)

Engine在SqlAlchemy负责管理通往数据的连接,相当于底层数据库在SqlAlchemy中的代理,结构如下:

Engine是面对用户的数据库接口,DBAPI是DB的API接口。Pool是通向DB的连接池,Dialect代表了底层数据库的类型。
使用SqlAlchemy.create_engine(*args,**kwargs)方法就可以指定数据库引擎了。相关参数如下:
connect_args :连接参数,格式如下:
    dialect+driver://user:password@host/dbname[?key=value.]
    dialect代表底层数据库类型,如MySql, oracle 等
    driver代表数据库驱动,如psycopg2, pyodbc,不填将根据数据库类型使用对应的默认驱动。
    之后就是数据库的连接参数:用户名,密码,IP地址,端口,数据库名,以及传递给connect方法的附加参数。
    例如,Quantum的 Plugin OpenvSwitch的connect_args如下:
    mysql://root:nova@127.0.0.1:3306/ovs_quantum
convert_unicode = False:是否要将python 的Unicode对象转化为String类型,在使用不支持python Unicode的数据库时应为true
creater:连接者,当包含这个参数的时候, connect_args参数将被忽略。将使用指定的creater来建立通往DB的连接。
echo = False : 是否对所有命令进行日志记录,输出地默认为sys.stout,即控制台的CMD界面。
echo_pool = False : 是否记录连接与断开连接信息,输出地默认为sys.stout。
encoding = uft-8 编码格式。
execution_options : 对所有连接应用的附加选项,比如自动提交。
implicit_returning = True不太肯定这个参数的意思。官方的说明如下:
    When True, a RETURNING- compatible construct, if available, will be used to fetch newly generated primary key values when a single row INSERT statement is emitted with no existing returning() clause. This applies to those backends which support RETURNING or a compatible construct, including Postgresql, Firebird, Oracle, Microsoft SQL Server. Set this to False to disable the automatic usage of RETURNING.
label_length = None :数据表中列的上限,None表示无限制,实际上使用dialect.max_identifier_length,即对应数据库支持最大值。
listeners 连接池事件的监听者。
logging_name 记录日志的名称。
max_overflow = 10 允许的最大额外连接数量,这些连接会被挂起,进入队列等待,直到连接池有空余位置。实际上标志了等待队列的大小。
module = None ,引入的python 模型,通常用来指定外部的DBAPI,当参数为None时,将使用默认的DBAPI.
pool = None 连接池对象,需为SqlAlchemy中Pool类型或其子类的实例,当参数为None时候,将使用连接参数来构造连接池,非None时,将使用pool指定的连接池
poolclass = None 使用连接参数构造连接池时的pool类型。需要为Pool的子类。参数为None时,将使用Pool类型。
pool_longging_name 连接池日志的名字,默认将使用对象的哈希值
pool_size = 5 连接池中允许的并发连接数量,不同的子连接类型对于无限连接的设置可能不同,请参阅相关文档。
pool_recycle = -1 ,连接回收时间,单位为秒,即当超过连接时间时,连接将被回收。-1表示不回收。实际上不同的数据库还有自己的默认回收时间。对于MySql,若连接在8小时内无动作时将启动自动回收。
pool_reset_on_return = ‘roolback’, 不理解这个参数的意思,原文如下:
    set the “reset on return” behavior of the pool, which is whether rollback(), commit(), or nothing is called upon connections being returned to the pool.
pool_timeout = 30 从连接池中获取连接的超时时间,仅对pool为Queuepool时有效。
strategy = ‘plain’:Engine的执行策略。决定Engine执行命令的方式,相关参数含义不太肯定,请参阅官方文档。

create_engine方法具有丰富的定制参数,实际上在使用的时候,除去connect_args之外,其余的只要使用默认参数,SqlAlchemy就可以工作的很好。

在建立Engine之后,还需要指定Engine的对象-数据表映射类型,使用register_models方法。方法如下:
def register_models(base=BASE):
    """Register Models and create properties"""
    global _ENGINE
    assert _ENGINE
    try:
        base.metadata.create_all(_ENGINE)
    except sql.exc.OperationalError as e:
        LOG.info(_("Database registration exception: %s"), e)
        return False
    return True
其实是调用了declarative_base方法。declarative_base方法具有许多参数可以选择不同的映射方法,参见官方说明文档。至此,就可以使用SqlAlchemy对数据库进行操作了。

2. 定义数据类

数据库中的数据表在Python中体现为类,这种类需要是之前声明的BASE的子类才可以进行映射。在Quantum中,端口类的定义如下:
class Port(model_base.BASEV2, HasId, HasTenant):
    """Represents a port on a quantum v2 network."""
    name = sa.Column(sa.String(255))
    network_id = sa.Column(sa.String(36), sa.ForeignKey("networks.id"),
                           nullable=False)
    fixed_ips = orm.relationship(IPAllocation, backref='ports', lazy="dynamic")
    mac_address = sa.Column(sa.String(32), nullable=False)
    admin_state_up = sa.Column(sa.Boolean(), nullable=False)
    status = sa.Column(sa.String(16), nullable=False)
    device_id = sa.Column(sa.String(255), nullable=False)
    device_owner = sa.Column(sa.String(255), nullable=False)
Port类型是BASEV2(我使用的是G版)的子类,符合映射条件。
__tablename__ 是数据库中port类对应的表名,是必须的参数,每个类与数据表一一对应。表名是在QuantumBaseV2类中定义:
class QuantumBaseV2(QuantumBase):

    @declarative.declared_attr
    def __tablename__(cls):
        # NOTE(jkoelker) use the pluralized name of the class as the table
        return cls.__name__.lower() + 's'
uuid, network_id, 等属性分别是表中的数据字段,使用SqlAlchemy的Column类型进行定义。Column类的完整构造参数列表参见相关文档。Column中使用的常见参数如下:
数据类型 :String(String_length), integer, Boolean
主键 : primary_key
外键 : ForeignKey(外键表.键名)
可否为空 : nullable
是否自动增长: autoincrement
除Column数据字段之外,还可以使用SqlAlchemy的relation为表建立关系,如Quantum DB中的network:
class Network(model_base.BASEV2, HasId, HasTenant):
    """Represents a v2 quantum network."""
    name = sa.Column(sa.String(255))
    ports = orm.relationship(Port, backref='networks')
    subnets = orm.relationship(Subnet, backref='networks')
    status = sa.Column(sa.String(16))
    admin_state_up = sa.Column(sa.Boolean)
    shared = sa.Column(sa.Boolean)
network中的 ports就是指向类Port的关系集合,关于relationship的构造参数请参考官方文档。

3. 增删改查

有了数据引擎和数据表之后就可以对数据库进行增删改查操作了。
首先,需要建立通往数据库的会话(Session),相关的方法为:
sqlalchemy.orm.session.sessionmaker()。Quantum中使用get_session方法进行封装,简化操作,如下所示:
def get_session(autocommit=True, expire_on_commit=False):
    """Helper method to grab session"""
    global _MAKER, _ENGINE
    if not _MAKER:
        assert _ENGINE
        _MAKER = sessionmaker(bind=_ENGINE,
                              autocommit=autocommit,
                              expire_on_commit=expire_on_commit)
    return _MAKER()
相关参数的含义:
bind : 表示绑定的数据engine, 也可以使用单独的URL表示数据链接,在Quantum中直接使用了定义好的engine,
autocommit 表示是否使用自动提交,当参数为True时候会话不会保持数据库事务的持久运行,只在需要的时候建立通往数据库的连接,默认为Fasle, Quantum封装默认为True.
expire_on_commit表示会话实例是否在Commit()操作后持久化连接。默认为True, 这样随后的操作就可以及时的从连接中获得最新的数据库状态,但是需要消耗资源维持连接,Quantum封装默认为False。
其他参数请参阅官方文档。

get_session()返回一个session对象,有以下方法:
session.query() 查询记录
session.add()  增加记录
session.flush()  提交记录
session.delete()  删除记录
以上方法的时候,可以参考OpenStack任意一个组件的数据库操作代码。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值