dbt 增量策略模型实战教程
上文我们介绍了增量策略的理论知识,本文结合实际场景介绍如何合理利用增量策略,内容包括应用场景、常见问题及解决方案。
应用场景
增量模型是定义如何增量向数据模型添加数据的有效方法——假设我们有描述信用卡交易的数据表——我们创建DBT模型,内容如下:
{{config(materialized="table",) }}
selecttransaction_id,transaction_date,user_id,store_name_description,transaction_amount
from {{ ref('external_table_transaction') }}
这将在目标数据库中创建一张表,从表external_table_transaction加载事务数据。问题是,每次我们重新运行这个查询时,它都会重新加载整个表——表中的数据越多,我们的查询就会变得越慢,运行时间越长——解决该问题的方法是使用增量模型:
{{config(materialized="incremental",unique_key=["transaction_id"],incremental_strategy="delete+insert",) }}
selecttransaction_id,transaction_date,user_id,store_name_description,transaction_amount
from {{ ref('external_table_transaction') }}
{%- if is_incremental() %}where transaction_date = (select max(transaction_date) + 1 as next_date from {{ this }})
{%- endif %}
我们看到宏函数及jinja模版功能让DBT如此强大。上面代码基本实现了我们的诉求,现在应该只从external_table_transaction加载事务增量数据,其中transaction_date
比表中的最新数据大1天——它简单而强大。我们现在只需要处理以前看不见的行,而不是处理每次更新都会变大的数十亿行数据;如果需要,仍然可以选择完全刷新重新加载全部数据。
问题分析
增量模型非常吸引人——它们在逻辑上非常漂亮,在定期处理数据流的情况下,效率非常高。当我们需要控制正在处理哪些数据时,问题就出现了:增量模型不能处理需要重新运行特定分区的情况,而是根据增量模型的规则加载数据。
也许从理论上讲,这不是问题,因为如果增量模型在理想环境中运行,所有数据将只加载一次。但现实是混乱的——数据处理流程中断,数据延迟交付,或者在某些情况下根本不交付,有时我们需要重新加载历史记录。此外,如果调度dbt任务程序出错,也会需要重新运行弥补问题。典型造成问题的场景如下:
-
数据流中原始一些数据需要回溯加载2年前的修复数据,我们需要加载历史数据,这需要以一种特殊的方式完成,因为增量策略无法加载2年前的历史记录。
-
数据流由于上游问题而中断了3天,3天没有加载数据,当数据流在第4天运行时,它正在加载第1天的数据-换句话说,它已经不同步其他数据。当然我们可以修改条件,加载大于最大日期数据,但是即使这样也会因为日期问题漏加载数据。
-
数据流的上游有跳过日(缺少数据的日子),我们的增量模型试图通过在数据中的最大日期上添加“1”来加载数据,但该日期从未出现,因此数据从未加载,导致需要人工干预。
即使有这些问题,我们也不能简单放弃增量模型,对于大数据量场景,处理任务是非常缓慢、且成本高。
- 幂等和分区
增量模型的关键问题是它们不是幂等的,并且不能配置为针对特定日期分区运行。对于幂等脚本可以多次重新运行而不会产生副作用。如果历史数据有问题,我们总是可以重新生成一些特定的分区——由于脚本是幂等的,我们可以在给定的一天内多次运行,而不会产生任何问题。
增量模型不具备重新运行数据的特定分区的能力——相反,它们将所有数据视为流,只加载看不见的数据——基本上加载满足特定规则的数据,而不是数据的特定分区。
问题是有时我们需要数据流符合某种时间分区运行——可以是每小时、每天、每周、每月。如果我们重新运行数据流任务,希望它在对应的时间分区上运行;但是同时也需要增量模型只会“向前看”,而不是在历史分区上配置。总之,就是既要增量、又要灵活按时间分区幂等方式运行。
解决方案
解决方案很简单:我们可以使用DBT变量,并且不需要完全抛弃增量模型的功能。我们可以添加变量来显式地针特定分区运行:
{%- set target_date = var("target_date", "") %}
{{config(materialized="incremental",unique_key=["transaction_id"],incremental_strategy="delete+insert", ) }}
selecttransaction_id,transaction_date,user_id,store_name_description,transaction_amount
from {{ ref('external_table_transaction') }}
{%- if target_date != "" %}where transaction_date = '{{ target_date }}'
{%- else %}{%- if is_incremental() %}where transaction_date = (select max(transaction_date) + 1 as next_date from {{ this }}){%- endif %}
{%- endif %}
这里在DBT模型添加了’ target_date ‘变量。如果’ target_date '未定义,则模型将以增量行为运行,但如果传入变量,则模型将针对指定分区运行。当通过调度程序执行时,这种方式会工作得很好。
此外,我们采用"delete+insert"
增量策略,模型现在已经变成幂等的——假设源数据是相同的,我们可以用相同的参数运行相同的查询,并期望得到相同的结果——而对于增量模型,加载的数据取决于表的内容,以及上游发生的更改。
这个解决方案有效地为我们提供了三种模式: 完全重新加载、增量加载和分区加载。因此在实际应用中非常实用,而且可以很好地配合Airflow或其他调度工具实现自动化运行:
dbt run --select my_model-- 显示完全刷新数据模型
dbt run --select my_model --full-refresh-- 指定参数执行
dbt run --select my_model --vars "{target_date : '2024-01-01'}"
最后总结
本文介绍了增量策略实际应用中的问题:如何让增量模型能够高效幂等运行。我们提供良好的解决方案同时满足三种场景应用,让数据转换流程更健壮、更高效。期待您的真诚反馈,更多内容请阅读数据分析工程专栏。
相关文章:
dbt 增量策略模型实战教程
上文我们介绍了增量策略的理论知识,本文结合实际场景介绍如何合理利用增量策略,内容包括应用场景、常见问题及解决方案。 应用场景 增量模型是定义如何增量向数据模型添加数据的有效方法——假设我们有描述信用卡交易的数据表——我们创建DBT模型&#…...

【含文档】基于Springboot+Android的校园论坛系统(含源码+数据库+lw)
1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统定…...
Go版数据结构 -【8.4 快速排序】
8.4 快速排序 快速排序是一种分而治之的排序算法。它通过随机选择一个基准元素,将数组分为两部分。 一部分比基准元素小,另一部分比基准元素大,之后对两部分排序。 快速排序以其平均情况下的 O(n log n) 时间复杂度和良好的性能而广泛应用…...

达梦DBLINK访问ORACLE配置方法
目录 1、概述 2、测试环境 3、语法简介 4、配置访问DM的DBLINK 5、配置访问ORACLE的DBLINK 5.1 通过OCI配置 5.2 通过ODBC配置 1、概述 本文介绍了达梦DBLINK的配置方法。有3部分内容,1)达梦访问到达梦的配置方法;2)通过OC…...
基础知识1
目录 1、gcd最大公因数 2、最小公倍数 3、素数问题 ①简单数学求法 ②素数筛 ③线性筛 1、gcd最大公因数 int gcd(int a,int b){return b0?a:gcd(b,a%b);} 做题过程中,如果数据太大,需要边做边对分子分母进行约分 2、最小公倍数 int a,b;scanf(&…...
网页前端开发之Javascript入门篇(9/9):对象
Javascript对象 什么是对象? 答:其概念跟 Python教程 的字典基本相似,虽然存有一些差异,不过对于目前的教程来讲可以忽略。 下面是对象的语法: var aaa {"弓" : "张","木" : "李",&…...

Oracle RAC IPC Send timeout detected问题分析处理
一、报错信息 今天在进行数据库巡检时,在集群节点1发现了IPC相关报错信息: 2024-10-10T10:22:06.84631708:00 IPC Receiver dump detected. Sender instance 2 Receiver pnum 277 ospid 377527 [oraclezxsszpt-sjkfwq1 (PPA6)], pser 124403 2024-10-1…...

QT 实现QMessageBox::about()信息自定义显示
这是我记录Qt学习过程的第四篇心得文章,主要是方便自己编写的应用程序显示“关于信息”,对QMessageBox::about()输入信息进行规范,可以设置应用程序名称,通过定义宏从pro文件获取应用程序版本号,以及编译程序的QT版本、…...
(C++进阶)C++20
目录 一、概述 二、新特性 1. 模块(Modules)功能 2. 概念(Concepts)功能 3. 范围(Ranges)功能 4. 协程(Coroutines)功能 5. 三路比较运算符(Spaceship Operator&a…...
【常用的安装破解版指令】MAC安装破解版软件显示文件损坏时
MAC安装破解版软件显示文件损坏时 复制以下命令粘贴到终端后 sudo xattr -rd com.apple.quarantine 打开Finder(访达),点击左侧的 应用程序,将应用拖进终端中,然后按键盘的回车键(return)&…...
【QT Quick】定时器和线程:定时器Timer
在现代用户界面开发中,动态更新内容、处理定时任务或异步任务是常见的需求,尤其在复杂应用中可能会遇到界面阻塞的问题。在 Qt Quick 中,定时器(Timer)和多线程是两种主要的解决方案,用于避免这种阻塞现象。…...

【NIO基础】NIO(非阻塞 I/O)和 IO(传统 I/O)的区别,以及 NIO 的三大组件详解
目录 1、NIO 2、NIO 和 IO 的区别 1. 阻塞 vs 非阻塞 2. 一个线程 vs 多个连接 3. 面向流 vs 面向缓冲 4. 多路复用 3、Channel & Buffer (1)Channel:双向通道 (2)Buffer:缓冲区 (3)ByteBufferÿ…...

HDLBits中文版,标准参考答案 | 3.1.3 Arithmetic Circuits | 算术电路
关注 望森FPGA 查看更多FPGA资讯 这是望森的第 10 期分享 作者 | 望森 来源 | 望森FPGA 目录 1 Half adder | 半加器 2 Full adder | 全加器 3 3-bit binary adder | 3位二进制加法器 4 Adder | 加法器 5 Signed addition overflow | 有符号数的加法溢出 6 100-bit bi…...
网络编程 websocket
1. HTTP 截至 2024 年,HTTP(HyperText Transfer Protocol)已经发展到 HTTP/3 版本。 各个版本的简介: HTTP/0.9(1991年): 最初的 HTTP 版本,非常简单,仅支持 GET 方法…...
【JDK17 | 5】Java 17 深入剖析:新的随机数生成器 API
引言 在 Java 17 中,新的随机数生成器 API 作为一个重要特性被引入,旨在提供更灵活和高效的随机数生成方案。新的 API 不仅支持多种生成算法,还改善了随机数生成的性能,适应了现代开发的需求。在本篇文章中,我们将深入…...

剪切走的照片:高效恢复与预防策略
一、剪切走的照片现象描述 在日常的数字生活中,照片作为记录生活点滴、工作成果的重要载体,其重要性不言而喻。然而,有时我们可能会遇到一种令人头疼的情况:原本打算通过剪切操作将照片移动到另一个位置,却意外地发现…...

基于XGBoost的结核分枝杆菌的耐药性预测研究【多种机器学习】
1. 绪论 目录 1. 绪论 1.1研究背景及意义 1.2国内外研究现状 1.2.1国内研究现状 1.2.2国外研究现状 1.3研究目的 2. 相关技术概念 2.1结核分枝杆菌的耐药性机制 2.2机器学习与系统发育法相结合 2.3XGBoost和随机森林算法的优势和应用 3. 模型设计 3.1数据准备与预…...

【C++差分数组】3229. 使数组等于目标数组所需的最少操作次数|2066
本文涉及知识点 C差分数组 LeetCode3229. 使数组等于目标数组所需的最少操作次数 给你两个长度相同的正整数数组 nums 和 target。 在一次操作中,你可以选择 nums 的任何子数组,并将该子数组内的每个元素的值增加或减少 1。 返回使 nums 数组变为 tar…...
浅谈PyTorch中的DP和DDP
目录 1. 引言2. PyTorch 数据并行(Data Parallel, DP)2.1 DP 的优缺点2.2 DP 实现代码示例 3. PyTorch 分布式数据并行(Distributed Data Parallel, DDP)3.1 DDP 的优缺点3.2 分布式基本概念3.3 DDP 的应用流程3.5 DDP 实现代码示…...

在Windows上利用谷歌浏览器进行视频会议和协作
随着远程工作和在线教育的普及,使用谷歌浏览器在Windows上进行视频会议和协作变得越来越常见。本文将为您提供一个详细的教程,教您如何在Windows上利用谷歌浏览器进行视频会议和协作,同时解决一些常见的问题。(本文由https://goog…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...

大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...

使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...