OpenGauss数据库之Python驱动快速入门

2021-04-04 吴京京

OpenGauss数据库之Python驱动

openGauss是一款开源关系型数据库管理系统,采用木兰宽松许可证v2发行。openGauss内核源自PostgreSQL,深度融合华为在数据库领域多年的经验,结合企业级场景需求,持续构建竞争力特性。

可是目前针对于OpenGauss数据库的Python应用程序的开发少之又少,这其中的一个原因在于不知道用什么驱动来连接该数据库,特别是Python应用程序,在此我将给大家介绍如何使用Python驱动连接OpenGauss数据库,同时翻译了psycopg2的文档:psycopg2中文文档,目前仍在维护和调整中,如果有任何建议,欢迎提PR来进行修正。

一、数据库部署

教程的第一步当然是引导大家部署数据库了,由于OpenGauss数据库与操作系统有一定的依赖关系,为了屏蔽掉不同操作系统之间部署的区别,我推荐使用Docker来进行部署,部署的脚本如下所示:

# 1.拉取镜像
docker pull enmotech/opengauss

# 2.开启opengauss数据库服务
docker run --name opengauss \
    --privileged=true -d \
    -e GS_USERNAME=gaussdb \
    -e GS_PASSWORD=Secretpassword@123 \
    -p 5432:5432 \
    enmotech/opengauss:latest

在以上代码中,默认数据库用户名为gaussdb,数据库密码为Secretpassword@123,开启服务的端口为5432,相信熟悉Docker的同学一眼就能看明白代码的含义。

可是在此部署的镜像当中只存在一个默认数据库:gaussdb,如果要添加新的数据库节点的话可以使用以下代码:

# 1. 进入运行的Docker容器
docker exec -it opengauss /bin/bash

# 2. 设置环境变量
export GAUSSHOME=/usr/local/opengauss
export PATH=$GAUSSHOME/bin:$GAUSSHOME:$GAUSSHOME/lib:$PATH
export LD_LIBRARY_PATH=$GAUSSHOME/lib:$LD_LIBRARY_PATH
export DATADIR='/var/lib/opengauss/data'

# 3. 使用gsql登陆opengauss数据库
gsql -U gaussdb -W Secretpassword@123 -d postgres -p 5432

# 4. 创建test_db数据库
CREATE DATABASE test_db WITH ENCODING 'UTF8' template = template0;

# 5. 重新加载OpenGauss数据库
gs_ctl reload -D $DATADIR

以上命令执行完毕之后即可创建对应的数据库。

安装教程

要想使用Python驱动在OpenGauss数据库上开发应用,非常简单,只需要安装以下包即可:

pip install psycopg2-binary

安装步骤只需要一步即可,接下来就可以开始应用程序的开发。

Simple Operations with OpenGauss

为了演示与数据库的基本操作,我将从创建会话连接、创建表、插入数据、修改数据、删除数据以及查询数据等六个方面来演示。

任何数据库的操作都是需要先创建连接来管理对应的事务,OpenGauss也不例外:

创建会话连接

from psycopg2 import connect


def create_conn():
    """get connection from envrionment variable by the conn factory

    Returns:
        [type]: the psycopg2's connection object
    """
    env = os.environ
    params = {
        'database': env.get('OG_DATABASE', 'opengauss'),
        'user': env.get('OG_USER', 'gaussdb'),
        'password': env.get('OG_PASSWORD', 'Secretpassword@123'),
        'host': env.get('OG_HOST', '127.0.0.1'),
        'port': env.get('OG_PORT', 5432)
    }
    conn: connection = connect(**params)
    return conn

以上代码中从环境变量中获取对应配置,从而创建与数据库的会话连接。

创建表

所有的数据操作都是在表上的操作,所以接下来就是需要创建对应的表:

def create_table(conn):
    """check and create table by example

    Args:
        table_name (str): the name of the table
        corsor (type): the corsor type to get into operation with db
    """
    sql = f"""SELECT EXISTS 
        (
            SELECT 1 
            FROM pg_tables
            WHERE tablename = '{table_name}'
        );"""
    with conn:
        with conn.cursor() as cursor:
            cursor.execute(sql)
            result = cursor.fetchone()
            if not result[0]:
                logger.info(f'creating table<{table_name}>')
                sql = f"""CREATE TABLE {table_name} (id serial PRIMARY KEY, name varchar, course varchar, grade integer);"""
                result = cursor.execute(sql)
                conn.commit()

以上代码中,首先是检测斗对应的表是否存在,如果不存在的话,便创建对应的表。

插入数据

def insert_data(conn) -> int:
    """insert faker data

    Args:
        cnn ([type]): the connection object to the databse
    """
    faker = Faker(locale=['zh-cn'])
    sql = f"insert into {table_name} (name, course, grade) values (%s,%s,%s) RETURNING *;"
    with conn:
        with conn.cursor() as cursor:
            age = random.randint(20, 80)
            result = cursor.execute(sql, (faker.name(), faker.name(), age))
            result = cursor.fetchone()
            logger.info(f'add data<{result}> to the databse')
            conn.commit()
    return result[0] if result else None

使用SQL语句来插入数据,语法与Mysql等数据库有些不一样,可是大同小异,都是能够看懂。在语句的后面返回当前操作的结果,也就是能够获取插入数据的ID。

修改数据

def update_data(conn, student):
    """insert faker data

    Args:
        cnn ([type]): the connection object to the databse
    """
    faker = Faker(locale=['zh-cn'])
    sql = f"update {table_name} name=%s, course=%s, grade=%s where id={student.id};"
    with conn:
        with conn.cursor() as cursor:
            age = random.randint(20, 80)
            result = cursor.execute(sql, (faker.name(), faker.name(), age))
            result = cursor.fetchone()
            logger.info(f'update data<{result}> to the databse')
            conn.commit()

修改数据只需要使用以上代码的SQL语句即可,相信熟悉SQL的同学一眼就能看懂。

接下来就是删除数据了:

删除数据

def delete_data_by_id(conn, id: int):
    """delete data by primary key

    Args:
        conn ([type]): the connection object
        id (int): the primary key of the table
    """
    sql = f"delete from {table_name} where id = %s;"
    with conn:
        with conn.cursor() as cursor:
            cursor.execute(sql, (id,))
            logger.info(f'delete data from databse by id<{id}>')

获取数据

def get_data_by_id(conn, id: int):
    """fetch data by id

    Args:
        conn ([type]): the connection object
        id (int): the primary key of the table

    Returns:
        [type]: the tuple data of the table
    """
    sql = f"select * from {table_name} where id = %s;"
    with conn:
        with conn.cursor() as cursor:
            cursor.execute(sql, (id,))
            result = cursor.fetchone()
            logger.info(f'select data<{result}> from databse')
    return result

在以上代码中,通过SELECT语句筛选出对应的数据,这个接口是非常简单且通用的。

在以上代码中有一个规律,所有的操作都是需要在Cursor上进行操作,这是因为每一个原子事务的控制都是基于cursor对象,这样通过细粒度的控制能够很好的调度应用程序中所有的数据库交互操作。

在以上代码中,展示了最简单的数据连接与数据库查询,使用方法非常简单,并符合DB API v2的规范,从而让很多上有工具原生支持opengauss的操作,比如可直接在Sqlalchemy ORM工具中连接Opengauss数据库,这是一个非常重要的特性。

此处只是一个非常简单的数据库连接示例,后续我将持续发布一些深入的使用Opengauss Python数据库驱动的案例,录制了一个线上视频提供参考:

BiliBili-opengauss使用之python驱动

总结

Opengauss数据库是一个可处理高并发的高性能数据库,基于PostgreSql生态可轻松实现Python驱动应用程序的开发。

【免责声明】本文仅代表作者本人观点,与本网站无关。本网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文仅供读者参考,由此产生的所有法律责任均由读者本人承担。