openEuler22+GreatSQL+dbops玩转MGR

Posted GreatSQL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了openEuler22+GreatSQL+dbops玩转MGR相关的知识,希望对你有一定的参考价值。

芬达,《芬达的数据库学习笔记》公众号作者,开源爱好者,擅长 MySQL、ansible。

背景

openEuler 是什么

openEuler22.03 LTS 是 openEuler 社区于 2022 年 3 月发布的开源操作系统(从系统版本的命名不难发现吧)。openEuler 社区的运营由华为为主导,社区以全球开源贡献者的合作,构建了这个高效、稳定和安全的操作系统。基于 Linux 内核的 openEuler 操作系统,支持 Kunpeng 以及其他处理器,旨在充分发挥计算芯片的潜力。它适用于数据库、大数据、云计算和人工智能等场景。通过社区合作,openEuler 构建了一个创新平台,创建了一个支持多处理器架构的统一开放操作系统,并推动了软件和硬件应用生态系统的繁荣。

openEuler22.03 LTS 带来了一系列关键功能,包括基于 Linux Kernel 5.10 的深度优化、新型媒体文件系统、分层内存扩展、用户模式协议栈、云原生调度增强、QEMU 热补丁、KubeOS、增强的轻量级安全容器、增强的 iSulad、双平面部署、边缘计算支持、嵌入式镜像,以及 secPaver 等。

openEuler22.03 LTS 可以被视为国产操作系统创新项目的首选系统版本之一。

GreatSQL 是什么

GreatSQL,作为 MySQL 分支 Percona 的延伸,立志成为中国广泛受欢迎的开源数据库。其上一版本基于 Percona Server 8.0.25 构建,而这次的新版本则使用 Percona Server 8.0.32 作为基础,引入了许多重要特性。新发布的 GreatSQL 8.0.32-24 版本增加了并行 load data、逻辑和 CLONE 备份加密、MGR 读写节点可动态绑定 VIP、SQL 兼容扩展、审计日志增强等重大特性。

GreatSQL 8.0.32-24 可以被视为国产开源数据库信创项目,并且解决 MySQL5.7 EOL 问题的重要替代方案之一。

关于 MySQL5.7 EOL 问题,可以翻阅我之前写的文章《阴谋论: MySQL 将死,国产数据库的春天?》

dbops 是什么

dbops 是一款提供生产级别 MySQL 部署的 playbook 工具,由芬达个人开发。

地址: https://gitee.com/fanderchan/dbops/

GreatSQL 官方并未提供专门针对 openEuler 的编译安装包,而我发现部署 GreatSQL、GreatSQL MGR、GreatSQL HA 等都有许多细节需要注意。本文主要讲述我如何思考并开发 dbops 的新功能,以在 openEuler22 上成功部署 GreatSQL,并运行其"MGR 读写节点可动态绑定 VIP"功能(以下简称"GreatSQL HA 功能")。

dbops 如何支持 GreatSQL

dbops 本来就支持 MySQL 和 Percona,所以对 GreatSQL 的支持并不需要大规模的改动。以下大部分是一些针对部署 GreatSQL 与 MySQL 或 Percona 的不同之处的调整。

1. 只对 Linux - Generic 包的支持

由于 dbops 的目标是支持大量的国产操作系统,与 MySQL 一样,GreatSQL 提供了针对各种操作系统的预编译二进制包,但有一个是通用的,那就是 Linux - Generic 包。在 dbops 为 MySQL 提供支持以及在实际生产中,都在使用这个包。

同时,为了支持更多的 Linux 系统,我选择了基于 glibc2.17 的包,而非 glibc2.28 的包。前者意味着包是在 glibc 公共库版本为 2.17 的系统下编译出来的,因此,它不会包含大于 2.17 的库函数,兼容性会更强。

我选择支持的是 minimal 包,这个版本剔除了与调试相关的二进制文件和调试符号,体积非常小,仅为常规包的三分之一,我认为非 minimal 包并无优势。

目前,dbops 仅支持 GreatSQL-8.0.32-24-Linux-glibc2.17-x86_64.tar.xz 的部署。

2. dbops 的 mysql_ansible 的配置文件 common_config.yml 的调整

dbops 可以很方便的配置执行 playbook 的变量,变量设置非常集中,一般只需要修改两个文件,一个是全局参数配置文件 common_config.yml,另外一个是当前需要执行的 playbook yaml 文件。

  • 新增了 db_type 参数,用于判断待部署的数据库类型,可选值为 MySQL、Percona、GreatSQL。根据 db_type 的不同,部署流程将有所区别。
  • 将 mysql_base_dir 参数和 mysql_data_dir_base 参数设定为根据 db_type 自动生成,这样可以得到不同的目录路径。我希望避免将 MySQL 和 GreatSQL 放置在同一目录下,以便于区分。
  • 对于 mysql_package 参数,即安装包的名称,如果是 MySQL,会根据 mysql_version 自动生成;如果是 GreatSQL,将读取 greatsql_package 的设置。
  • 新增了 fcs_use_greatsql_ha 开关参数,其默认值为 1,即如果部署的是 GreatSQL 并且采用 MGR 架构(执行的 playbook==mgr.yml),那么默认会部署"MGR 读写节点可动态绑定 VIP"的功能插件。
## DB TYPE,suport mysql,percona,greatsql
+ db_type: greatsql

#Directory of MySQL installation package
mysql_packages_dir: ../downloads/ 

+ greatsql_package: GreatSQL-8.0.32-24-Linux-glibc2.17-x86_64-minimal.tar.xz
+ percona_package: Percona-Server-8.0.29-21-Linux.x86_64.glibc2.17.tar.gz

## do not modify
- mysql_package: " \'mysql-\' + mysql_version + \'-linux-\' + (\'glibc2.12\' if mysql_version.startswith(\'5.\') else \'glibc2.17\') + \'-x86_64\' + (\'.tar.gz\' if mysql_version.startswith(\'5.\') else \'-minimal.tar.xz\') "
+ mysql_package: "% if db_type == \'mysql\' % \'mysql-\' + mysql_version + \'-linux-\' + (\'glibc2.12\' if mysql_version.startswith(\'5.\') else \'glibc2.17\') + \'-x86_64\' + (\'.tar.gz\' if mysql_version.startswith(\'5.\') else \'-minimal.tar.xz\') % elif db_type == \'percona\' % percona_package % elif db_type == \'greatsql\' % greatsql_package % endif %"

## linux mysql run user name
mysql_user: mysql
mysql_group: mysql
mysql_user_password: Dbops@9999

## mysql install directory
- mysql_base_dir: /database/mysql/base/ mysql_version 
+ mysql_base_dir: /database/ db_type /base/ mysql_version 

## mysql_data_dir_base define mysql datadir base, real datadir= mysql_data_dir_base + /port
- mysql_data_dir_base: /database/mysql
+ mysql_data_dir_base: /database/ db_type 

+ fcs_use_greatsql_ha: 1

3. 新增 GreatSQL 专属 my.cnf 模板,并对 GreatSQL HA 的新参数支持

在 mgr.yml 这个 playbook 里新增三个与 GreatSQL HA 相关的参数设置

+ greatsql_vip: 192.168.199.174
+ greatsql_net_work_interface: "ens33"
+ greatsql_netmast: "255.255.255.255"

新增了 mysql_ansible/roles/mysql_server/templates/8.0/greatsql-my.cnf.j2 模板,此模板是从 percona-my.cnf.j2 模板克隆而来。为了支持 GreatSQL HA 的相关参数设置,我使用 jinja2 语法设置了判断逻辑,只有满足以下三个条件,才会添加这些参数:

  • 数据库类型为 \'greatsql\' (在 common_config.yml 中设置)
  • 设置了 fcs_use_greatsql_ha: 1 开关,要求部署 GreatSQL HA 功能(在 common_config.yml 中设置)
  • 在安装 MGR 时(运行 ansible-playbook mgr.yml 时)
+ % if db_type == \'greatsql\' and fcs_use_greatsql_ha == 1 and make_mgr_role_included is defined and make_mgr_role_included %
+ #GreatSQL MGR vip
+ plugin-load-add=greatdb_ha.so
+ loose-greatdb_ha_enable_mgr_vip=1
+ loose-greatdb_ha_mgr_vip_ip= greatsql_vip 
+ loose-greatdb_ha_mgr_vip_mask= greatsql_netmast 
+ loose-greatdb_ha_mgr_vip_nic= greatsql_net_work_interface 
+ 
+ #single-primary mode
+ loose-group_replication_single_primary_mode=1
+ loose-group_replication_enforce_update_everywhere_checks=0
+ % endif %

前面设置的三个参数值,greatsql_vip、greatsql_netmast、greatsql_net_work_interface 会对应传入到 my.cnf 里。

4. 支持自动下载 GreatSQL 安装包

+ - name: Download GreatSQL binary tarball if not found locally and auto download is enabled(local)
+   ansible.builtin.get_url:
+     url: "https://product.greatdb.com/ mysql_package[0:18] / mysql_package "
+     dest: " mysql_packages_dir / mysql_package "
+     mode: \'0644\'
+     timeout: 30
+     headers:
+       User-Agent: "Wget/1.21.1"
+   when: not mysql_server__package_file.stat.exists and fcs_auto_download_mysql == 1 and db_type == \'greatsql\'
+   delegate_to: 127.0.0.1

在正常情况下,您应该手动上传 GreatSQL 的包到 downloads/ 文件夹中。如果在 downloads/ 文件夹中没有找到对应的包,且在 common_config.yml 文件中设置了 fcs_auto_download_mysql == 1(允许从互联网下载安装包),并且 db_type == \'greatsql\',那么将会自动从互联网下载安装包。

dbops 本身就支持下载 MySQL 安装包的功能。但由于 GreatSQL 的安装包下载路径不同,因此我额外添加了一个下载链接,以实现相同的下载功能。

5. 修改 GreatSQL 启动服务

为了让 GreatSQL HA 支持 mysqld 执行通常需要较高权限才能操作的挂载和卸载 VIP 操作,我们需要进行一些特殊设置。官方原先提供了两个方案,但我提出了新的解决方案。

在服务设置中,我们加入以下代码:

[Service]
+ % if db_type == \'greatsql\' and fcs_use_greatsql_ha == 1 and make_mgr_role_included is defined and make_mgr_role_included %
+ AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW
+ % endif %

只有当满足条件(需要部署 GreatSQL HA)时,系统会自动在启动服务中配置 "CAP_NET_ADMIN CAP_NET_RAW" 的权限。

![图片](data:image/svg+xml,%3C%3Fxml version=\'1.0\' encoding=\'UTF-8\'%3F%3E%3Csvg width=\'1px\' height=\'1px\' viewBox=\'0 0 1 1\' version=\'1.1\' xmlns=\'http://www.w3.org/2000/svg\' xmlns:xlink=\'http://www.w3.org/1999/xlink\'%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=\'none\' stroke-width=\'1\' fill=\'none\' fill-rule=\'evenodd\' fill-opacity=\'0\'%3E%3Cg transform=\'translate(-249.000000, -126.000000)\' fill=\'%23FFFFFF\'%3E%3Crect x=\'249\' y=\'126\' width=\'1\' height=\'1\'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)

我设计的这种方法也得到了官方的采纳,成为首选推荐方法。

6. fix 部署 GreatSQL 有可能报错的问题

GreatSQL 在部署后可能在使用 mysqld 初始化时,或者初始化后使用 mysql 登录时,报告 libcrypto.so 或 libssl.so 找不到。

[root@192-168-199-171 ~]# /usr/local/mysql/bin/mysqld --defaults-file=/database/mysql/etc/3306/my.cnf --initialize-insecure
/usr/local/mysql/bin/mysqld: error while loading shared libraries: libcrypto.so: cannot open shared object file: No such file or directory

[root@192-168-199-171 lib]# mysql -uroot -p -S /database/mysql/data/3307/mysql.sock
mysql: error while loading shared libraries: libssl.so: cannot open shared object file: No such file or directory

针对此问题,我们有两种解决方案。第一种方法是使用 yum install openssl-devel 安装,之后系统库就会包含这两个 so 库:

/usr/lib64/libcrypto.so
/usr/lib64/libssl.so

然而,我们也有第二种解决方法。GreatSQL 的 Generic 包其实已经编译了这两个库,只是它们被命名为 libcrypto.so.10 和 libssl.so.10,而非 libcrypto.so 和 libssl.so。我们只需在 /usr/local/mysql/lib/private/ 文件夹内为这两个库创建软链接即可。

并且,我认为采用第二种方法,使用官方包内的 libcrypto.so 和 libssl.so,是最佳的解决方案。

改动代码如下:

mysql_ansible/roles/mysql_server/tasks/fix_greatsql_install.yml

+ - name: Create symbolic links for libssl.so and libcrypto.so
+   file:
+     src: "/usr/local/mysql/lib/private/ link.src "
+     dest: "/usr/local/mysql/lib/private/ link.dest "
+     state: link
+     owner: " mysql_user "
+     group: " mysql_group "
+   loop:
+     -  src: \'libssl.so.10\', dest: \'libssl.so\' 
+     -  src: \'libcrypto.so.10\', dest: \'libcrypto.so\' 
+   loop_control:
+     loop_var: link

mysql_ansible/roles/mysql_server/tasks/main.yml

  - name: Install mysql to /usr/local/mysql
    ansible.builtin.import_tasks: install_mysql.yml

+ - name: Fix libcrypto.so and libssl.so not find by create link if db_type is greatsql
+   ansible.builtin.import_tasks: fix_greatsql_install.yml
+   when: db_type == \'greatsql\'

  - name: Init mysql datadir
    ansible.builtin.import_tasks: initialize_mysql_datadir.yml

7. 检查网卡是否一致

在设定了 VIP 漂移的三台机器中,与 MHA 架构相同,我们可能会遇到一种状况:在一开始设置网卡绑定时,主机管理员可能会没注意,发生以下情况:

192.168.199.171  网卡名 bond1
192.168.199.172  网卡名 bond1
192.168.199.173  网卡名 bond0

你可能已经发现了,第三台机器的网卡名与前两台不一致。因此,如果发生高可用漂移,MHA 或 MGR 在选择主机时,如果选择了第三台作为主机,那么根据 greatsql_net_work_interface: "bond1" 的设置,漂移操作可能会失败。虽然我还没有进行过测试,但这个问题在 MHA 架构中肯定会发生,而且在 GreatSQL HA 架构中也有很大可能发生!

因此,在运行 ansible-playbook 部署 mgr.yml 时,我已在第一步的 pre_check_and_set(检查和设置系统参数)中,加入了检查网卡名是否一致的步骤。如果网卡名不一致,playbook 将报错并终止运行,给出提示。代码如下:

- name: Add network interface alias to a temporary file
  ansible.builtin.lineinfile:
    path: "/tmp/net_aliases.txt"
    line: " ansible_default_ipv4.alias "
    create: true
    mode: \'0644\'

- name: Fetch copy
  ansible.builtin.fetch:
    src: /tmp/net_aliases.txt
    dest: /tmp/ssh

- name: Append file /tmp/net_aliases.txt (delegate to 127.0.0.1)
  ansible.builtin.shell: set -o pipefail && find /tmp/ssh/ -name "*.txt" -type f -exec sh -c \'cat \' \\; | sort | uniq | wc -l
  register: pre_check_and_set__shell_output
  changed_when: false
  run_once: true
  delegate_to: 127.0.0.1

- name: Check if shell output is 1
  ansible.builtin.assert:
    that: pre_check_and_set__shell_output.stdout | int == 1
    fail_msg: "Network card names are different!"
  run_once: true
  delegate_to: 127.0.0.1

- name: Delete /tmp/net_aliases.txt
  ansible.builtin.file:
    path: /tmp/net_aliases.txt
    state: absent

- name: Delete /tmp/ssh/ (delegate to 127.0.0.1)
  ansible.builtin.file:
    path: /tmp/ssh/
    state: absent
  run_once: true
  delegate_to: 127.0.0.1

8. 支持使用 jemalloc 内存分配器

GreatSQL 和 Percona 官方都推荐使用 jemalloc 替代默认的 malloc,我至今没有发现 MySQL 官方的类似建议。然而,在实践中,我曾经通过替换 malloc 为 jemalloc 内存管理器来解决内存泄露问题,尽管根本原因仍不清楚。因此,我之前已经在我的 dbops 工具中加入了在部署时选择使用 jemalloc 内存分配器的功能,它是在 systemd 服务中实现的。

以下是涉及的代码:

mysql_ansible/playbooks/common_config.yml

# 配置文件中提供一个开关,决定是否使用 jemalloc 内存分配器,其默认值为 0,即不修改内存分配器
fcs_mysql_use_jemalloc: 1

mysql_ansible/roles/mysql_server/tasks/install_mysql_dependents.yml

- name: Install libaio and numactl
  ansible.builtin.yum:
    name: " package.name "
    state: present
  loop:
    -  name: \'libaio\' 
    -  name: \'numactl\' 
  loop_control:
    loop_var: package
  tags:
    - dependents

- name: Install jemalloc
  when: fcs_mysql_use_jemalloc == 1
  tags:
    - dependents
  block:
    - name: Install jemalloc using yum
      ansible.builtin.yum:
        name: jemalloc
        state: present
      register: mysql_server__jemalloc_install_result
      ignore_errors: true

    - name: Set jemalloc rpm file name based on OS
      ansible.builtin.set_fact:
        mysql_server__jemalloc_rpm_file: " \'jemalloc-3.6.0-1.el8.x86_64.rpm\' if os_type in [\'openEuler22\', \'openEuler20\', \'CentOS8\', \'BigCloud8\', \'Anolis OS8\'] else \'jemalloc-3.6.0-1.el7.x86_64.rpm\' "

    - name: Copy jemalloc rpm to target server
      ansible.builtin.copy:
        src: "../files/ mysql_server__jemalloc_rpm_file "
        dest: "/tmp/ mysql_server__jemalloc_rpm_file "
        mode: \'0755\'
      when: mysql_server__jemalloc_install_result.failed

    - name: Install jemalloc from local file
      ansible.builtin.yum:
        name: "/tmp/ mysql_server__jemalloc_rpm_file "
        state: present
        disable_gpg_check: true
      register: mysql_server__jemalloc_local_install_result
      when: mysql_server__jemalloc_install_result.failed
      ignore_errors: true

    - name: Check if jemalloc installation failed
      ansible.builtin.fail:
        msg: "Failed to install jemalloc"
      when: mysql_server__jemalloc_install_result.failed and mysql_server__jemalloc_local_install_result.failed

这段代码主要是用于安装 mysql_server 的依赖包,如果你在配置中设置了 fcs_mysql_use_jemalloc: 1,那么将会安装 jemalloc。默认情况下,它会尝试使用 yum 来安装。如果 yum 安装失败,那么它会尝试使用 dbops 自带的 jemalloc 包。

原因是,预备的 jemalloc 包只有两个版本:一个是针对 EL7,一个是针对 EL8。并没有专门为国产操作系统准备的专用包。在国产操作系统上,你应该优先使用 yum 来安装适合该系统的包。如果使用 yum 安装失败,你可以考虑使用 EL7 或者 EL8 的 jemalloc 包来进行兼容性安装。

mysql_ansible/roles/mysql_server/templates/mysql.service.j2

[Service]
...
% if fcs_mysql_use_jemalloc == 1 %
% if os_type in [\'openEuler22\',\'openEuler20\'] %
Environment="LD_PRELOAD=/usr/lib64/libjemalloc.so.2"
% else %
Environment="LD_PRELOAD=/usr/lib64/libjemalloc.so.1"
% endif %
% endif %

根据 yum 或者 rpm 包方式安装 libjemalloc 后,不同操作系统的 libjemalloc.so 路径可能会不同,我在服务配置里会做判断和正确加载。

结语与反馈征集

如果你对 dbops 感兴趣,欢迎你使用,并提出宝贵的建议或问题。如果在使用过程中遇到任何问题,或有任何改进的建议,欢迎在 dbops 的 gitee 项目页面上提交 issue。你的反馈将帮助我不断改进,使其更好地服务于所有开源数据库用户。

我会认真处理每一个提交的 issue,力求在第一时间给出解答或解决方案。同时,我们也欢迎你为 dbops 的开发做出贡献,无论是提交代码,还是参与讨论,我都非常欢迎。感谢你的支持!


Enjoy GreatSQL

Python:将带有pandas的SQL结果读取到用于for循环的列表中时出现问题

【中文标题】Python:将带有pandas的SQL结果读取到用于for循环的列表中时出现问题【英文标题】:Python: Problem reading SQL results with pandas into list to be used in for loop 【发布时间】:2020-07-04 14:46:36 【问题描述】:

我是 Python 新手。

我有两个 SQL 视图。

DBOP4 和 DBOP4_SELECTION

DBOP4 包含许多列和许多行。 DBOP4 的一列是 SaBeNummerDebitoren。

DBOP4_SELECTION:

SELECT        SaBeNummerDebitoren AS SBNr, [Sachbearbeiter Debitoren] AS SBName
FROM            dbo.DBOP4
GROUP BY SaBeNummerDebitoren, [Sachbearbeiter Debitoren]

我尝试编写一个 python 脚本,输出 DBOP4 的结果,为 SaBeNummerDebitoren 中的每个现有值分开。

import pandas as pd
import pyodbc 
conn = pyodbc.connect('Driver=SQL Server;'
                      'Server=***;'
                      'Database=***;'
                      'Trusted_Connection=yes;')

cursor = conn.cursor()
 
SQL_SBNR_Selection = pd.read_sql_query('SELECT SBNR FROM DBOP4_SBSELECTION' ,conn)
print(SQL_SBNR_Selection)
#print(type(SQL_SBNR_Selection))

#Sachbearbeiternummer = ('1258','1278','1290')
Sachbearbeiternummer = pd.DataFrame(SQL_SBNR_Selection)

for sachbearbeiternr in Sachbearbeiternummer:
    print("Starte " + str(sachbearbeiternr))
    sql_query = pd.read_sql_query('SELECT *  FROM DBOP4 Where [SaBeNummerDebitoren] =' +str(sachbearbeiternr) ,conn)
    print(sql_query)
    print(type(sql_query))

    df = pd.DataFrame(sql_query)

    df.to_excel (r'C:\OP\export_dataframe '+str(sachbearbeiternr)+'.xlsx', sheet_name='DBOP4_' +str(sachbearbeiternr) , index = False, header=True, freeze_panes=(1,5))
      

print("Fertig")

输出如下:

     SBNR
0  1258.0
1  1278.0
2  1290.0
Starte SBNR

调试信息:

Exception has occurred: DatabaseError
Execution failed on sql 'SELECT *  FROM DBOP4 Where [SaBeNummerDebitoren] =SBNR': ('42S22', "[42S22] [Microsoft][ODBC SQL Server Driver][SQL Server]Ungültiger Spaltenname 'SBNR'. (207) (SQLExecDirectW)")
  File "C:\AzureDevopsRepos\Python Skripte\PythonApplication1\PythonApplication1.py", line 20, in <module>
    sql_query = pd.read_sql_query('SELECT *  FROM DBOP4 Where [SaBeNummerDebitoren] =' +str(sachbearbeiternr) ,conn)

问题: for 循环不会对列表中的每个数字('1258'、'1278'、'1290')重复 excel 导出。

当我确实像这样填充 Sachbearbeiternummer Sachbearbeiternummer = ('1258','1278','1290') 该脚本有效。

问题 1: 循环以列 SBNR 的名称而不是第一个值开始。

问题 2: 尝试使用 SBNR 后循环不会继续。 如果我只是在 for 循环中执行 print("Starte " + str(sachbearbeiternr)),它也会在 SBNR 之后停止。

如果有人能帮我解决我的问题,我会很好。

【问题讨论】:

【参考方案1】:

目前,您的 for 循环 (for sachbearbeiternr in Sachbearbeiternummer) 遍历数据框的列,然后您将其传递到查询中,而不用引号括住文字值。这就是错误将第一列名称SNBR 指向无效名称的原因。

一个直接的解决方法是遍历数据框的特定列(或系列),然后使用 read_sql_queryparams 参数将查询参数化。顺便说一句,没有必要在read_sql_query 之后调用DataFrame,因为文档表明方法的返回值是DataFrame。另外,Pandas-SQL 操作不需要游标。

# ITERATE ACROSS COLUMN OR SERIES
for sachbearbeiternr in Sachbearbeiternummer['SBNR']:
    print("Starte " + str(sachbearbeiternr))
    ...
    # BIND ITERATOR VALUE AS PARAMETER
    sql_query = pd.read_sql_query('SELECT * FROM DBOP4 WHERE [SaBeNummerDebitoren] = ?',
                                  conn, params = [sachbearbeiternr])
    

话虽如此,不需要第二个查询或数据框。只需导入 整个 视图,然后运行 ​​Pandas 的 groupby() 以通过 SaBeNummerDebitoren 的不同值拆分数据框。从那里,迭代和处理每个子集。

df_DBOP4 = pd.read_sql_query('SELECT *  FROM DBOP4', conn)

# SPLIT DATA FRAME BY COLUMN: i IS SPLIT VALUE, g IS SUBSET DF
for i,g in df_DBOP4.groupby(['SaBeNummerDebitoren']):
    print("Starte " + str(i))        
    print(g.head(10))           # FIRST 10 ROWS

    df.to_excel(r'C:\OP\export_dataframe 0.xlsx'.format(i), 
                sheet_name='DBOP4_'+str(i), index = False, 
                header=True, freeze_panes=(1,5))

【讨论】:

以上是关于openEuler22+GreatSQL+dbops玩转MGR的主要内容,如果未能解决你的问题,请参考以下文章

openEuler-22.03系统安装openGauss3.0.0 企业版过程中遇到的坑

openEuler-22.03系统安装openGauss3.0.0 企业版过程中遇到的坑

openEuler 22.03-LTS 基础配置

Kubeadm 快速搭建 k8s v1.24.1 集群(openEuler 22.03 LTS)

OpenEuler切换内核的方法-bcc学习后续

openEuler RISC-V 成功适配 VisionFive 2 单板计算机