Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
Amazon-Selection-Data
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abel_cjy
Amazon-Selection-Data
Commits
b6374899
Commit
b6374899
authored
Jun 16, 2026
by
hejiangming
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
no message
parent
35d1e0b5
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
164 additions
and
14 deletions
+164
-14
dwt_aba_last365.py
Pyspark_job/dwt/dwt_aba_last365.py
+31
-2
dwt_aba_st_analytics.py
Pyspark_job/dwt/dwt_aba_st_analytics.py
+111
-2
dwt_aba_last365.py
Pyspark_job/sqoop_export/dwt_aba_last365.py
+10
-1
dwt_aba_st_analytics.py
Pyspark_job/sqoop_export/dwt_aba_st_analytics.py
+12
-9
No files found.
Pyspark_job/dwt/dwt_aba_last365.py
View file @
b6374899
...
@@ -331,9 +331,32 @@ class DwtAbaLast365(object):
...
@@ -331,9 +331,32 @@ class DwtAbaLast365(object):
),
),
''
''
)
)
"""
)
.
alias
(
'st_attribute_label'
)
"""
)
.
alias
(
'st_attribute_label'
),
# 峰值月中间值:最小 rank(排名最好)+ (rank,月份) 明细数组(下面算 peak_month 用)
F
.
min
(
"rank"
)
.
alias
(
"min_rank"
),
F
.
collect_list
(
F
.
struct
(
"rank"
,
"date_info"
))
.
alias
(
"rank_arr"
),
# 常年可卖:近 12 个月都出现在 ABA 月度搜索词中(去重月份数=12)→ 1,否则 0
F
.
when
(
F
.
size
(
F
.
collect_set
(
"date_info"
))
>=
12
,
F
.
lit
(
1
))
.
otherwise
(
F
.
lit
(
0
))
.
alias
(
"all_year_text_flag"
)
)
)
# 峰值月 peak_month:从 rank_arr 里 filter 出 rank=min_rank 的项 → 取 date_info → 排序 → 拼成 'YYYY-MM' 逗号串
# 并列峰值全保留;与月表 dwt_aba_st_analytics 同口径同格式
# nullif 兜底:极端 rank 全 null 时 filter 为空 → 空串 → 转 null → 由 handle_save 的 na.fill 转空串 → PG string_to_array 转空数组 {}
df_agg
=
df_agg
.
withColumn
(
"peak_month"
,
F
.
expr
(
"""
nullif(
concat_ws(',',
array_sort(transform(
filter(rank_arr, x -> x.rank = min_rank),
x -> x.date_info
))
),
''
)
"""
)
)
.
drop
(
"min_rank"
,
"rank_arr"
)
# 行转列的字段
# 行转列的字段
agg_col_arr
=
[
'st_num'
,
'bsr_orders'
,
'orders'
,
'market_cycle_type'
,
'search_volume'
]
agg_col_arr
=
[
'st_num'
,
'bsr_orders'
,
'orders'
,
'market_cycle_type'
,
'search_volume'
]
self
.
df_base
=
self
.
pivot_df
(
self
.
df_base
=
self
.
pivot_df
(
...
@@ -614,6 +637,10 @@ class DwtAbaLast365(object):
...
@@ -614,6 +637,10 @@ class DwtAbaLast365(object):
F
.
col
(
"appear_month_lastest"
),
F
.
col
(
"appear_month_lastest"
),
#搜索词属性标签(12 个月合并去重,逗号分隔字符串,sqoop 导出 PG 后转 VARCHAR[])
#搜索词属性标签(12 个月合并去重,逗号分隔字符串,sqoop 导出 PG 后转 VARCHAR[])
F
.
col
(
"st_attribute_label"
),
F
.
col
(
"st_attribute_label"
),
# 峰值月:近12个月 rank 最小的月份,并列保留,'YYYY-MM' 逗号分隔(与月表同口径)
F
.
col
(
"peak_month"
),
# 常年可卖:近12个月每月都出现在 ABA 月度搜索词中=1,否则=0
F
.
col
(
"all_year_text_flag"
),
F
.
lit
(
self
.
site_name
)
.
alias
(
"site_name"
),
F
.
lit
(
self
.
site_name
)
.
alias
(
"site_name"
),
F
.
lit
(
self
.
date_type
)
.
alias
(
"date_type"
),
F
.
lit
(
self
.
date_type
)
.
alias
(
"date_type"
),
...
@@ -655,7 +682,9 @@ class DwtAbaLast365(object):
...
@@ -655,7 +682,9 @@ class DwtAbaLast365(object):
"top_rank"
:
0
,
"top_rank"
:
0
,
# handle_agg 里 12 月全 -1 时输出空串 → nullif 转 null → 这里 fillna '-1'
# handle_agg 里 12 月全 -1 时输出空串 → nullif 转 null → 这里 fillna '-1'
# 占位 "-1" 与 dwt_aba_st_analytics 端规则一致,Java 转 null 返前端
# 占位 "-1" 与 dwt_aba_st_analytics 端规则一致,Java 转 null 返前端
"st_attribute_label"
:
"-1"
"st_attribute_label"
:
"-1"
,
# 峰值月极端兜底(rank 全 null)→ nullif 转 null → 这里 fillna 空串,PG string_to_array 转空数组 {}(与月表同规则)
"peak_month"
:
""
})
.
cache
()
})
.
cache
()
def
save_data
(
self
):
def
save_data
(
self
):
...
...
Pyspark_job/dwt/dwt_aba_st_analytics.py
View file @
b6374899
...
@@ -9,6 +9,7 @@ from pyspark.sql import functions as F
...
@@ -9,6 +9,7 @@ from pyspark.sql import functions as F
from
pyspark.sql.types
import
IntegerType
from
pyspark.sql.types
import
IntegerType
from
utils.db_util
import
DBUtil
from
utils.db_util
import
DBUtil
from
utils.spark_util
import
SparkUtil
from
utils.spark_util
import
SparkUtil
from
utils.common_util
import
CommonUtil
from
yswg_utils.common_udf
import
udf_detect_phrase_reg
from
yswg_utils.common_udf
import
udf_detect_phrase_reg
...
@@ -57,6 +58,9 @@ class DwtAbaStAnalytics(Templates):
...
@@ -57,6 +58,9 @@ class DwtAbaStAnalytics(Templates):
# 搜索词属性标签 df,来源 dws_st_theme 聚合 theme_ch(材质/颜色/细分人群等)
# 搜索词属性标签 df,来源 dws_st_theme 聚合 theme_ch(材质/颜色/细分人群等)
# 仅 month 流程在 read_data 阶段真正读取数据;非 month 流程下游统一用 lit("-1") 填充
# 仅 month 流程在 read_data 阶段真正读取数据;非 month 流程下游统一用 lit("-1") 填充
self
.
df_st_attribute
=
self
.
spark
.
sql
(
f
"select 1+1;"
)
self
.
df_st_attribute
=
self
.
spark
.
sql
(
f
"select 1+1;"
)
# 自身历史 11 个月分区的 rank(峰值月 peak_month / 常年可卖 all_year_text_flag 计算用)
# 仅 month 流程在 read_data 阶段真正读取数据;非 month 流程下游统一用占位值填充
self
.
df_history_rank
=
self
.
spark
.
sql
(
f
"select 1+1;"
)
# 自定义udf函数注册
# 自定义udf函数注册
self
.
u_contains
=
self
.
spark
.
udf
.
register
(
'u_contains'
,
self
.
udf_contains
,
IntegerType
())
self
.
u_contains
=
self
.
spark
.
udf
.
register
(
'u_contains'
,
self
.
udf_contains
,
IntegerType
())
...
@@ -343,6 +347,13 @@ class DwtAbaStAnalytics(Templates):
...
@@ -343,6 +347,13 @@ class DwtAbaStAnalytics(Templates):
and date_info = '{self.date_info}'
and date_info = '{self.date_info}'
"""
"""
self
.
df_st_detail
=
self
.
spark
.
sql
(
sqlQuery
=
sql
)
self
.
df_st_detail
=
self
.
spark
.
sql
(
sqlQuery
=
sql
)
# ============================================================
# 清洗品牌/类目字段里的 \x00(NUL 字节) 脏数据流到本表后,sqoop 导出 PG 会报
# 注意:不洗 search_term/asin1-3——search_term 是后续所有 join 的 key,
# 单独在这里洗会和其他上游表的 key 对不上,导致数据悄悄丢失
# ============================================================
for
col
in
[
'st_brand1'
,
'st_brand2'
,
'st_brand3'
,
'st_category1'
,
'st_category2'
,
'st_category3'
]:
self
.
df_st_detail
=
self
.
df_st_detail
.
withColumn
(
col
,
F
.
regexp_replace
(
F
.
col
(
col
),
'
\x00
'
,
''
))
self
.
df_st_detail
=
self
.
df_st_detail
.
repartition
(
80
,
'search_term'
)
.
cache
()
self
.
df_st_detail
=
self
.
df_st_detail
.
repartition
(
80
,
'search_term'
)
.
cache
()
print
(
"self.df_st_detail:"
)
print
(
"self.df_st_detail:"
)
self
.
df_st_detail
.
show
(
10
,
truncate
=
True
)
self
.
df_st_detail
.
show
(
10
,
truncate
=
True
)
...
@@ -535,6 +546,30 @@ class DwtAbaStAnalytics(Templates):
...
@@ -535,6 +546,30 @@ class DwtAbaStAnalytics(Templates):
print
(
"self.df_st_attribute:"
)
print
(
"self.df_st_attribute:"
)
self
.
df_st_attribute
.
show
(
10
,
truncate
=
True
)
self
.
df_st_attribute
.
show
(
10
,
truncate
=
True
)
# ============================================================
# 读自身历史 11 个月分区的 rank,用于计算峰值月 peak_month / 常年可卖 all_year_text_flag
# 【为什么读自己而不读 dim_st_detail】:本表 month 分区从 2024-01 开始齐全,rank 字段
# 本身就来源于 dim_st_detail,读自己只需 3 列、无需兼容 month_old 老分区格式
# 【为什么只读 11 个月】:当月分区此时还没写入(本任务正在算),当月 rank
# 在 handle_peak_month 阶段直接从 df_save 里取,再和这 11 个月 union 凑满 12 个月窗口
# 【边界】:窗口内某月分区缺失(如词库早期月份),in 条件查不到就少一个月,
# 不影响 min(rank) 取峰值,只影响 all_year_text_flag(不满 12 个月必然=0,符合业务语义)
# ============================================================
last_11_month
=
[
CommonUtil
.
get_month_offset
(
self
.
date_info
,
-
i
)
for
i
in
range
(
1
,
12
)]
sql
=
f
"""
select
search_term,
rank,
date_info
from dwt_aba_st_analytics
where site_name = '{self.site_name}'
and date_type = 'month'
and date_info in ({CommonUtil.list_to_insql(last_11_month)})
"""
self
.
df_history_rank
=
self
.
spark
.
sql
(
sqlQuery
=
sql
)
.
repartition
(
80
,
'search_term'
)
.
cache
()
print
(
"self.df_history_rank:"
)
self
.
df_history_rank
.
show
(
10
,
truncate
=
True
)
def
handle_data
(
self
):
def
handle_data
(
self
):
# 对基础计算表进行关联
# 对基础计算表进行关联
self
.
handle_base_join
()
self
.
handle_base_join
()
...
@@ -553,8 +588,15 @@ class DwtAbaStAnalytics(Templates):
...
@@ -553,8 +588,15 @@ class DwtAbaStAnalytics(Templates):
if
self
.
date_type
==
'month'
:
if
self
.
date_type
==
'month'
:
self
.
handle_first_ever_flag
()
# 全历史首次出现标记(基于累加表 dim_st_detail_history) 不是月流程填充 -1
self
.
handle_first_ever_flag
()
# 全历史首次出现标记(基于累加表 dim_st_detail_history) 不是月流程填充 -1
self
.
handle_peak_month
()
# 峰值月 + 常年可卖(基于自身历史 11 个月分区 + 当月 rank)
else
:
else
:
self
.
df_save
=
self
.
df_save
.
withColumn
(
'is_first_ever_text'
,
F
.
lit
(
-
1
))
self
.
df_save
=
self
.
df_save
.
withColumn
(
'is_first_ever_text'
,
F
.
lit
(
-
1
))
# 非 month 流程业务不需要峰值月/常年可卖,直接占位(peak_month 空串→PG 转空数组 {},all_year_text_flag 占位 -1)
self
.
df_save
=
self
.
df_save
.
withColumn
(
'peak_month'
,
F
.
lit
(
''
)
)
.
withColumn
(
'all_year_text_flag'
,
F
.
lit
(
-
1
)
)
# 附加属性标签字段 st_attribute_label
# 附加属性标签字段 st_attribute_label
# month 流程:left join read_data 阶段已读取的 dws_st_theme 聚合结果,join 不上的词在 handle_column 阶段 fillna("-1")
# month 流程:left join read_data 阶段已读取的 dws_st_theme 聚合结果,join 不上的词在 handle_column 阶段 fillna("-1")
...
@@ -919,6 +961,69 @@ class DwtAbaStAnalytics(Templates):
...
@@ -919,6 +961,69 @@ class DwtAbaStAnalytics(Templates):
.
fillna
({
'is_first_ever_text'
:
1
})
.
fillna
({
'is_first_ever_text'
:
1
})
self
.
df_history_st
.
unpersist
()
self
.
df_history_st
.
unpersist
()
# 峰值月 + 常年可卖:基于近 12 个月(自身历史 11 个月分区 + 当月)的 rank 计算
def
handle_peak_month
(
self
):
"""
peak_month:近 12 个月窗口内 rank 最小(排名最好)的月份,并列全保留,
按时间升序逗号拼接,格式 'YYYY-MM'(如 '2025-11,2026-04')。
all_year_text_flag:近 12 个月每个月都出现在 ABA 月度搜索词中 → 1,否则 0(常年可卖)。
"""
# ============================================================
# Step 1:拼出完整 12 个月的 (search_term, rank, date_info) 明细
# 【为什么当月 rank 从 df_save 取】:当月分区还没写入 Hive,读不到自己;
# df_save 此时已含当月 rank(来源 dim_st_detail 的 st_rank,inner join 必有值)
# 【例子】:词 'water bottle',历史 11 个月出现 5 次 + 当月 1 行 → union 后 6 行
# ============================================================
df_current_rank
=
self
.
df_save
.
select
(
'search_term'
,
'rank'
,
F
.
lit
(
self
.
date_info
)
.
alias
(
'date_info'
)
)
df_rank_all
=
self
.
df_history_rank
.
unionByName
(
df_current_rank
)
# ============================================================
# Step 2:单次 groupBy 一并算出 最小 rank / (rank,月份)明细数组 / 去重月份数
# 【为什么不用 window 再 groupBy】:window.partitionBy('search_term') 和
# groupBy('search_term') 会按同一个 key 各洗一次 shuffle(df_rank_all ≈ 2000w 行),
# 把 min_rank 合进 groupBy 一次算完,省掉 window 那次 shuffle
# 【例子】:'water bottle' → min_rank=100, rank_arr=[(100,'2025-11'),(100,'2026-04'),(300,..)], month_cnt=6
# ============================================================
df_agg
=
df_rank_all
.
groupBy
(
'search_term'
)
.
agg
(
F
.
min
(
'rank'
)
.
alias
(
'min_rank'
),
F
.
collect_list
(
F
.
struct
(
'rank'
,
'date_info'
))
.
alias
(
'rank_arr'
),
F
.
count_distinct
(
'date_info'
)
.
alias
(
'month_cnt'
)
)
# ============================================================
# Step 3:map 端表达式算出 peak_month / all_year_text_flag(不触发 shuffle)
# 【peak_month 怎么算】:从 rank_arr 里 filter 出 rank=min_rank 的项 → transform 取 date_info
# → array_sort 保证时间升序、重跑结果稳定 → concat_ws 拼成逗号串
# 【例子】:min_rank=100,命中 '2025-11'、'2026-04' → peak_month='2025-11,2026-04'
# 【all_year_text_flag 怎么算】:去重月份数 = 12 → 常年可卖;只出现 6 个月 → 0
# 【nullif 兜底】:极端 rank 全 null(理论不会发生,rank 来源 inner join)时 filter 为空 →
# concat_ws 输出空串 '' → nullif 转 null → 由 handle_column 的 na.fill 转空串 → PG string_to_array 转空数组 {}
# ============================================================
df_peak
=
df_agg
.
select
(
'search_term'
,
F
.
expr
(
"""
nullif(
concat_ws(',',
array_sort(transform(
filter(rank_arr, x -> x.rank = min_rank),
x -> x.date_info
))
),
''
)
"""
)
.
alias
(
'peak_month'
),
F
.
when
(
F
.
col
(
'month_cnt'
)
>=
12
,
F
.
lit
(
1
))
.
otherwise
(
F
.
lit
(
0
))
.
alias
(
'all_year_text_flag'
)
)
# ============================================================
# Step 4:join 回 df_save
# 【为什么 left join 也必命中】:df_rank_all 包含当月全部词,df_peak 必有每个当月词
# ============================================================
self
.
df_save
=
self
.
df_save
.
join
(
df_peak
,
on
=
'search_term'
,
how
=
'left'
)
self
.
df_history_rank
.
unpersist
()
def
handle_column
(
self
):
def
handle_column
(
self
):
# 入库前字段处理,精度以 PG 集群列约束为基准
# 入库前字段处理,精度以 PG 集群列约束为基准
self
.
df_save
=
self
.
df_save
.
select
(
self
.
df_save
=
self
.
df_save
.
select
(
...
@@ -1030,7 +1135,9 @@ class DwtAbaStAnalytics(Templates):
...
@@ -1030,7 +1135,9 @@ class DwtAbaStAnalytics(Templates):
"is_first_ever_text"
,
# 需求2:全历史首次出现标记(1=当月首次, 0=历史出现过)
"is_first_ever_text"
,
# 需求2:全历史首次出现标记(1=当月首次, 0=历史出现过)
"brand_asin_proportion"
,
# 需求3:前三页ASIN数最多品牌的ASIN数占比
"brand_asin_proportion"
,
# 需求3:前三页ASIN数最多品牌的ASIN数占比
"seller_asin_proportion"
,
# 需求3:前三页ASIN数最多卖家的ASIN数占比
"seller_asin_proportion"
,
# 需求3:前三页ASIN数最多卖家的ASIN数占比
"st_attribute_label"
# 搜索词属性标签(逗号分隔字符串,sqoop 导出 PG 后转 VARCHAR[])
"st_attribute_label"
,
# 搜索词属性标签(逗号分隔字符串,sqoop 导出 PG 后转 VARCHAR[])
"peak_month"
,
# 峰值月:近12个月 rank 最小的月份,并列保留,'YYYY-MM' 逗号分隔(PG 转 VARCHAR[])
"all_year_text_flag"
# 常年可卖:近12个月每月都出现在 ABA 月度搜索词中=1,否则=0
)
)
# 空值处理
# 空值处理
...
@@ -1049,7 +1156,9 @@ class DwtAbaStAnalytics(Templates):
...
@@ -1049,7 +1156,9 @@ class DwtAbaStAnalytics(Templates):
"is_hidden_cate"
:
0
,
"is_hidden_cate"
:
0
,
"brand_asin_proportion"
:
-
1
,
# 需求3:分子为 null(搜索词全无品牌) → 占位 -1
"brand_asin_proportion"
:
-
1
,
# 需求3:分子为 null(搜索词全无品牌) → 占位 -1
"seller_asin_proportion"
:
-
1
,
# 需求3:分子为 null(搜索词全无账号) → 占位 -1
"seller_asin_proportion"
:
-
1
,
# 需求3:分子为 null(搜索词全无账号) → 占位 -1
"st_attribute_label"
:
"-1"
# 词典无匹配 → 占位 "-1"(Java 侧转 null 返前端)
"st_attribute_label"
:
"-1"
,
# 词典无匹配 → 占位 "-1"(Java 侧转 null 返前端)
"peak_month"
:
""
,
# 极端兜底(rank 全 null)→ 空串,PG string_to_array 转空数组 {}
"all_year_text_flag"
:
0
# 理论必有值,兜底 0(非 month 流程已提前填 -1,不受影响)
})
})
# 日期字段补全
# 日期字段补全
...
...
Pyspark_job/sqoop_export/dwt_aba_last365.py
View file @
b6374899
...
@@ -46,6 +46,7 @@ if __name__ == '__main__':
...
@@ -46,6 +46,7 @@ if __name__ == '__main__':
-- st_attribute_label 在正式表是 VARCHAR[],Sqoop 无法直接写入数组类型
-- st_attribute_label 在正式表是 VARCHAR[],Sqoop 无法直接写入数组类型
-- 先临时改成 VARCHAR(200) 让 Sqoop 写字符串,交换完成后再 ALTER 回 VARCHAR[]
-- 先临时改成 VARCHAR(200) 让 Sqoop 写字符串,交换完成后再 ALTER 回 VARCHAR[]
ALTER TABLE {export_tb_rel} ALTER COLUMN st_attribute_label TYPE VARCHAR(200);
ALTER TABLE {export_tb_rel} ALTER COLUMN st_attribute_label TYPE VARCHAR(200);
ALTER TABLE {export_tb_rel} ALTER COLUMN peak_month TYPE VARCHAR(200);
"""
"""
print
(
"================================执行sql================================"
)
print
(
"================================执行sql================================"
)
print
(
sql
)
print
(
sql
)
...
@@ -192,7 +193,11 @@ if __name__ == '__main__':
...
@@ -192,7 +193,11 @@ if __name__ == '__main__':
"rank_change_rate_lastest"
,
"rank_change_rate_lastest"
,
"rank_rate_of_change_lastest"
,
"rank_rate_of_change_lastest"
,
# 搜索词属性标签(12 个月合并去重,逗号分隔字符串,sqoop 导出 PG 后转 VARCHAR[])
# 搜索词属性标签(12 个月合并去重,逗号分隔字符串,sqoop 导出 PG 后转 VARCHAR[])
"st_attribute_label"
"st_attribute_label"
,
# 峰值月(近12月rank最小的月份,逗号分隔字符串,sqoop 导出 PG 后转 VARCHAR[])
"peak_month"
,
# 常年可卖标记(标量 int,sqoop 直写)
"all_year_text_flag"
],
],
partition_dict
=
{
partition_dict
=
{
"site_name"
:
site_name
,
"site_name"
:
site_name
,
...
@@ -227,6 +232,10 @@ if __name__ == '__main__':
...
@@ -227,6 +232,10 @@ if __name__ == '__main__':
ALTER TABLE {export_tb_before}
ALTER TABLE {export_tb_before}
ALTER COLUMN st_attribute_label TYPE VARCHAR[]
ALTER COLUMN st_attribute_label TYPE VARCHAR[]
USING string_to_array(st_attribute_label, ',')::varchar[];
USING string_to_array(st_attribute_label, ',')::varchar[];
ALTER TABLE {export_tb_before}
ALTER COLUMN peak_month TYPE VARCHAR[]
USING string_to_array(coalesce(peak_month, ''), ',')::varchar[];
alter table {export_tb_before} drop if exists keyword_tsv;
alter table {export_tb_before} drop if exists keyword_tsv;
alter table {export_tb_before} add column keyword_tsv tsvector generated always as (to_tsvector('english_amazonword', search_term)) STORED;
alter table {export_tb_before} add column keyword_tsv tsvector generated always as (to_tsvector('english_amazonword', search_term)) STORED;
...
...
Pyspark_job/sqoop_export/dwt_aba_st_analytics.py
View file @
b6374899
...
@@ -186,16 +186,18 @@ if __name__ == '__main__':
...
@@ -186,16 +186,18 @@ if __name__ == '__main__':
tb_cols
=
[
tb_cols
=
[
"is_new_market_segment"
,
"color_proportion"
,
"supply_demand"
,
"market_cycle_type"
,
"is_high_return_text"
,
"is_new_market_segment"
,
"color_proportion"
,
"supply_demand"
,
"market_cycle_type"
,
"is_high_return_text"
,
"st_zr_counts"
,
"st_sp_counts"
,
"st_self_asin_counts"
,
"st_self_asin_proportion"
,
"st_zr_counts"
,
"st_sp_counts"
,
"st_self_asin_counts"
,
"st_self_asin_proportion"
,
# 需求2 + 需求3:月度专属字段(仅 month 流程才有意义)
# is_first_ever_text 依赖累加表 dim_st_detail_history(仅 month 数据)
# brand_asin_proportion / seller_asin_proportion 服务月搜索词筛选页面
"is_first_ever_text"
,
"is_first_ever_text"
,
"brand_asin_proportion"
,
"brand_asin_proportion"
,
"seller_asin_proportion"
,
"seller_asin_proportion"
,
# 搜索词属性标签(材质/颜色/细分人群等),仅 month 计算
# 搜索词属性标签(材质/颜色/细分人群等),仅 month 计算
# Hive 端是逗号分隔 STRING(如 "材质,颜色"),sqoop 写入 PG copy 表需先 ALTER 成 VARCHAR
# Hive 端是逗号分隔 STRING(如 "材质,颜色"),sqoop 写入 PG copy 表需先 ALTER 成 VARCHAR
# 交换前再 ALTER 回 VARCHAR[](用 string_to_array 转换),与 dwt_aba_last365 处理 st_movie_brand_label 同款思路
# 交换前再 ALTER 回 VARCHAR[](用 string_to_array 转换),与 dwt_aba_last365 处理 st_movie_brand_label 同款思路
"st_attribute_label"
"st_attribute_label"
,
# 峰值月:Hive 端是逗号分隔 STRING(如 "2025-11,2026-04"),PG 端是 VARCHAR[]
# 同 st_attribute_label:copy 表先 ALTER 成 VARCHAR 让 sqoop 写字符串,交换前再 string_to_array 转回 VARCHAR[]
"peak_month"
,
# 常年可卖标记:标量 int,sqoop 直写,无需中转
"all_year_text_flag"
]
]
# 处理导出表
# 处理导出表
export_master_tb
=
f
"{export_base_tb}_{date_type}_{year_str}"
export_master_tb
=
f
"{export_base_tb}_{date_type}_{year_str}"
...
@@ -237,9 +239,9 @@ if __name__ == '__main__':
...
@@ -237,9 +239,9 @@ if __name__ == '__main__':
# copy 表继承自正式分区表(含 st_attribute_label VARCHAR[]),
# copy 表继承自正式分区表(含 st_attribute_label VARCHAR[]),
# 但 Sqoop 不支持直接写入 PG 数组类型,必须先把 copy 表的该列临时改成 VARCHAR
# 但 Sqoop 不支持直接写入 PG 数组类型,必须先把 copy 表的该列临时改成 VARCHAR
# 等 Sqoop 完成后、分区交换之前,再 ALTER 回 VARCHAR[](见下方 exchange_pg_part_tb 前的处理)
# 等 Sqoop 完成后、分区交换之前,再 ALTER 回 VARCHAR[](见下方 exchange_pg_part_tb 前的处理)
# 这是与 sqoop_export/dwt_aba_last365.py 中 st_movie_brand_label 同款的"VARCHAR 中转"模式
sql_alter_to_varchar
=
f
"""
sql_alter_to_varchar
=
f
"""
ALTER TABLE {export_tb_copy} ALTER COLUMN st_attribute_label TYPE VARCHAR(200);
ALTER TABLE {export_tb_copy} ALTER COLUMN st_attribute_label TYPE VARCHAR(200);
ALTER TABLE {export_tb_copy} ALTER COLUMN peak_month TYPE VARCHAR(200);
"""
"""
DBUtil
.
engine_exec_sql
(
engine
,
sql_alter_to_varchar
)
DBUtil
.
engine_exec_sql
(
engine
,
sql_alter_to_varchar
)
...
@@ -250,8 +252,6 @@ if __name__ == '__main__':
...
@@ -250,8 +252,6 @@ if __name__ == '__main__':
# "column keyword_tsv in child table must be a generated column"
# "column keyword_tsv in child table must be a generated column"
# 解决:显式 drop 后以生成列方式重建。CASCADE 是为了同时把 LIKE 时附带继承的 keyword_tsv 索引一并清掉,
# 解决:显式 drop 后以生成列方式重建。CASCADE 是为了同时把 LIKE 时附带继承的 keyword_tsv 索引一并清掉,
# 后面 ATTACH 时 master 的分区索引会自动给新分区补建对应索引。
# 后面 ATTACH 时 master 的分区索引会自动给新分区补建对应索引。
# 重建在 Sqoop 之前做:生成列由 search_term 自动计算(STORED),Sqoop 不写也不会报错。
# 参考 sqoop_export/dwt_aba_last365.py 中对 keyword_tsv 的同款处理。
sql_fix_keyword_tsv
=
f
"""
sql_fix_keyword_tsv
=
f
"""
ALTER TABLE {export_tb_copy} DROP COLUMN IF EXISTS keyword_tsv CASCADE;
ALTER TABLE {export_tb_copy} DROP COLUMN IF EXISTS keyword_tsv CASCADE;
ALTER TABLE {export_tb_copy} ADD COLUMN keyword_tsv tsvector
ALTER TABLE {export_tb_copy} ADD COLUMN keyword_tsv tsvector
...
@@ -311,12 +311,15 @@ if __name__ == '__main__':
...
@@ -311,12 +311,15 @@ if __name__ == '__main__':
elif
date_type
==
DateTypes
.
month
.
name
:
elif
date_type
==
DateTypes
.
month
.
name
:
# 分区交换前必须把 copy 表的 st_attribute_label 从 VARCHAR 转回 VARCHAR[]
# 分区交换前必须把 copy 表的 st_attribute_label 从 VARCHAR 转回 VARCHAR[]
# 否则与 master 分区表 schema 不一致,exchange_pg_part_tb 会失败
# 否则与 master 分区表 schema 不一致,exchange_pg_part_tb 会失败
# USING string_to_array(...) 把 Sqoop 写入的逗号串(如 "材质,颜色")拆成数组(如 {材质,颜色})
# USING string_to_array(...) 把 Sqoop 写入的逗号串(如 "材质,颜色")拆成数组(如 {材质,颜色}
# 词典无匹配的词,PySpark 已 fillna 为 "-1",转换后是 {-1},与 Java 占位约定一致
sql_alter_back
=
f
"""
sql_alter_back
=
f
"""
ALTER TABLE {export_tb_copy}
ALTER TABLE {export_tb_copy}
ALTER COLUMN st_attribute_label TYPE VARCHAR[]
ALTER COLUMN st_attribute_label TYPE VARCHAR[]
USING string_to_array(st_attribute_label, ',')::varchar[];
USING string_to_array(st_attribute_label, ',')::varchar[];
ALTER TABLE {export_tb_copy}
ALTER COLUMN peak_month TYPE VARCHAR[]
USING string_to_array(coalesce(peak_month, ''), ',')::varchar[];
"""
"""
DBUtil
.
engine_exec_sql
(
engine
,
sql_alter_back
)
DBUtil
.
engine_exec_sql
(
engine
,
sql_alter_back
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment