Backend - 不同DB数据库抛转数据( python 编写 ETL 工具)

文章介绍了如何在Django项目中设置多个PostgreSQL数据库连接,并展示了如何在`settings.py`中配置数据库,以及在`exc_etl.py`中执行查询、插入和更新数据的详细代码,包括使用ExcuteDB类进行数据库操作的方法.
摘要由CSDN通过智能技术生成

连接数据库,可参考另一篇文章:Backend - python 连接 & 操作 PostgreSQL DB(数据库)-CSDN博客

(一)settings.py文件

# 设定数据库
DATABASES = {
    'default': {  # 默认数据库
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'PORT': '5432',
        'NAME': 'Book',
        'USER': 'postgres',
        'PASSWORD': 'postgres',
        'HOST': 'XX.XXX.XX.XX',
    },
    'fromDB': {  # 来源数据库
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'PORT': '5432',
        'NAME': 'FrBook',
        'USER': 'postgres',
        'PASSWORD': 'postgres',
        'HOST': 'XX.XXX.XX.XX4',
    },
    'toDB': { # 目标数据库
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'PORT': '5432',
        'NAME': 'ToBook',
        'USER': 'postgres',
        'PASSWORD': 'postgres',
        'HOST': 'XX.XXX.XX.XX',
    },
}

(二)exc_etl.py 文件

from myApp.views.tools.excute_sql import ExcuteDB
from myProject.settings import DATABASES

def get_data():  # 在来源数据库中查询数据
    return 'select card from "myApp_book" limit 10'

def to_data():  # 新增数据至目的数据库
    return 'INSERT INTO auth_group (name) VALUES %s '

def edit_data():  # 在目的数据库中更新已有数据
    upd_sql = 'name=fr_book.name, btype=fr_book.btype ' # 两个表的字段匹配
    upd_col = 'name, btype' # 更新的字段
    return 'UPDATE "tb_book" SET {} FROM (VALUES %s) AS fr_book ({}) WHERE tb_book.bookid = fr_book.bookid;'.format(upd_sql, upd_col)

def handle_data(from_db, to_db):  # 处理数据
    try:
        get_sql = get_data()
        res_list = from_db.exc_query(get_sql)
        if res_list:
            to_db.exc_bulk_edit([{'sql': to_data(), 'args_list': res_list}] )
    except Exception as e:
        print(str(e) )

if __name__ == '__main__':  # 主程序
    try:
        # 设定来源DB
        from_dbname = DATABASES['fromDB']['NAME']
        from_user = DATABASES['fromDB']['USER']
        from_password = DATABASES['fromDB']['PASSWORD']
        from_port = DATABASES['fromDB']['PORT']
        from_host = DATABASES['fromDB']['HOST']
        from_db = ExcuteDB(from_host, from_dbname, from_user, from_port, from_password)        
        # 设定目的DB
        to_dbname = DATABASES['toDB']['NAME']
        to_user = DATABASES['toDB']['USER']
        to_password = DATABASES['toDB']['PASSWORD']
        to_port = DATABASES['toDB']['PORT']
        to_host = DATABASES['toDB']['HOST']
        to_db = ExcuteDB(to_host, to_dbname, to_user, to_port, to_password)
        
	   # 处理数据
        handle_data(from_db, to_db)
    except Exception as e:
        print(str(e) )

(三)excute_sql 文件

放置位置:myApp.views.tools 中

import psycopg2
from psycopg2.extras import execute_values
class ExcuteDB:
	# ————————————————————————————————————————————— 连接数据库
    def __init__(self, host, dbname, user, port, password):
        self.host = host
        self.dbname = dbname
        self.user = user
        self.port = port
        self.password = password
          # self.conn = self.__postgres  # 连接数据库(放在各种功能方法中,比如exc_query方法)
  
    @property
    def __postgres(self):
        conn = psycopg2.connect(host=self.host,  # 主机地址
                                dbname=self.dbname,  # 数据库名称
                                user=self.user,  # 用户名
                                password=self.password,  # 密码
                                port=self.port)  # 端口号
        return conn
	# ————————————————————————————————————————————— 查询
    def exc_query(self, sql):
        try:
            conn = self.__postgres  # 连接数据库
            cur = conn.cursor()  # 创建游标对象
            cur.execute(sql)  # 执行SQL语句
            res_list = None
            res_list = cur.fetchall()  # 获取记录值,结果是列表包元组:[('1F002', '数据结构怎么学'), ('1F001', '数据库原理')]
            cols_list = [row[0] for row in cur.description]  # 获取栏位名称['card', 'name']
            # data_list的第一种组成方法
            # 1. 结合map、lambda函数
            # 2. 必须先用一个变量存储cur.fetchall(),再执行下面的for循环
            data_list = [dict(map(lambda key, value: [key, value], cols_list, val_list)) for val_list in res_list]  # 组装列表包字典:data_list [{'card': '1F002', 'name': '数据结构怎么学'}, {'card': '1F001', 'name': '数据库原理'}]
            # data_list的另一种组成方法
            # 1. 结合zip函数
            # 2. 可以直接在for循环中使用
            # data_list = [dict(zip(cols_list, val_list)) for val_list in cur.fetchall()]
        except Exception as e:
            print(str(e))
        finally:
            cur.close()  # 关闭游标
            conn.close()  # 关闭数据库连接
		       return {'栏位名+栏位值': data_list, '只有栏位值': res_list}
	# ————————————————————————————————————————————— 单笔更新/插入
	def exc_edit(self, sql):
		        try:
		            conn = self.__postgres  # 连接数据库
		            cur = conn.cursor()  # 创建游标对象
		            cur.execute(sql)  # 执行SQL语句
		            conn.commit()  # 提交事务
		        except Exception as e:
		            conn.rollback()  # 回滚commit事务
		            print(str(e))
		        finally:
		            cur.close()  # 关闭游标
		            conn.close()  # 关闭数据库连接
	# ————————————————————————————————————————————— 批量更新/插入
    def exc_bulk_edit(self, sql_list):
        try:
            conn = self.__postgres  # 连接数据库
            cur = conn.cursor()  # 创建游标对象
            for l in sql_list:  # 循环不同的sql
                sql = l['sql']  # sql语句:'insert into auth_group (card, name, author, btype, price, num) values %s '
                args_list = l['args_list']  # 批量插入的值:[('2F0001', '高等数学', '小星星', '教育', 35, 10), ('2F0002', '线性代数', '小星星', '教育', 40, 12)]
                execute_values(cur, sql, args_list)  # 批量执行
            conn.commit()  # 提交事务
        except Exception as e:
            conn.rollback()  # 回滚commit事务
            print(str(e))
        finally:
            cur.close()  # 关闭游标
            conn.close()  # 关闭数据库连接

四、执行ETL项目

(一)执行项目

1. 执行 exc_etl.py 文件
(1)直接右键(选择终端运行)
(2)vscode 软件 debug 该文件(需放置在根目录下,然后launch.js配置)
{
    // 使用 IntelliSense 了解相关属性。 
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "myApp",
            "type": "python",
            "request": "launch",
            // "program": "${workspaceFolder}\\manage.py",
            "program": "${workspaceFolder}\\exc_etl.py", // ETL抛转数据执行档
            "args": [
                "runserver",
                "127.0.0.1:8080"
            ],
            "django": true,
            "justMyCode": true
        },
    ]
}
2. 生成执行exe档
(1)下载依赖:pyinstaller

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注:Python)

dnimg.cn/img_convert/9f49b566129f47b8a67243c1008edf79.png)

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注:Python)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值