phoenix表结构修改(新增字段,字段类型修改)


计划总是赶不上变化,在实际开发中,需求总会不断变更,比如需求开始只需要在phoenix中创建5个字段就可以,但随着业务的变化,需要新增一个字段,某个字段的数据类型也需要改变,这时简单粗暴的方式就是删表重建,再重跑数据。是否可以在phoenix中修改字段类型和添加字段呢?下面就来测试下:

修改思路

Phoenix表是映射的hbase表,hbase存储的数据都是字节数组,因此, 限制数据类型的只能是Phoenix自己,所以,我们就可以通过修改Phoenix元数据的方式修改表中字段的数据类型。

SYSTEM.CATALOG
SYSTEM.FUNCTION
SYSTEM.LOG
SYSTEM.SEQUENCE
SYSTEM.STATS

Phoenix的系统表有以上五张表, 其中SYSTEM.CATALOG表保存了我们新建表的元数据信息。

注:
这种方法只能修改char, varchar, DECIMAL类型的长度, 宽度等等, 不能将varchar修改为integer类型

开始操作

创建模拟表

create table test01_20200413 (
col1 integer not null primary key,
col2 varchar(2),
col3 varchar(5),
col4 decimal(4,2),
col5 decimal(6,3)
);

插入数据

插入数据时必须要有主键

upsert into test01_20200413 (COL1, COL2, COL3, COL4, COL5) values(1, '12', '12345', 12.12, 123.123);

select * from test01_20200413 t limit 2;

在这里插入图片描述

添加字段

alter table test01_20200413 add col6 bigint;

在这里插入图片描述

将新增的字段数据补齐

通过主键补齐新增字段数据

upsert into test01_20200413 (COL1, COL6) values(1, 321334);

--如果其他字段有新增需要更,加上更新字段和值就行
upsert into test01_20200413 (COL1, COL2, COL6) values(1, '13', 321334);

select * from test01_20200413 t where col1 = 1 limit 2;

在这里插入图片描述
在这里插入图片描述

删除字段

alter table test01_20200413 drop column col6;

在这里插入图片描述

查看元数据

注意:表名必须要大写,因为元数据中保存的是大写,并且区分大小写

select TENANT_ID,TABLE_SCHEM,TABLE_NAME,COLUMN_NAME,COLUMN_FAMILY,DATA_TYPE,COLUMN_SIZE,DECIMAL_DIGITS from SYSTEM.CATALOG where TABLE_NAME='TEST01_20200413';

在这里插入图片描述

字段名称字段含义
TENANT_ID租户ID(这个不用管,所租户用的)
TABLE_SCHEM表的schema
TABLE_NAME表名
COLUMN_NAME列名
COLUMN_FAMILhbase底层的列族名
DATA_TYPE列的数据类型
COLUMN_SIZE列的数据长度(一般指char,varchar和decimal的长度)
DECIMAL_DIGITSdecimal类型的小数长度

查看表的主键

--!primarykeys 表名
!primarykeys SYSTEM.CATALOG

在这里插入图片描述

修改元数据

将col2的字段类型由varchar(2) 改为varchar(4),
注意: 表名和字段必须为大写,不然无效
TENANT_ID,TABLE_SCHEM,TABLE_NAME,COLUMN_NAME,COLUMN_FAMILY 是主键, 必须要有

upsert into SYSTEM.CATALOG (TENANT_ID,TABLE_SCHEM,TABLE_NAME,COLUMN_NAME,COLUMN_FAMILY,COLUMN_SIZE) values('','','TEST01_20200413','COL2','0',4);

在这里插入图片描述

还是报错, 难道修改失败了???别着急, 退出Phoenix shell客户端,,再次进入Phoenix,就好了,因为我修改了phoenix元数据更新时间为一天,需要退出客户端重新进一下,重新加载元数据,然后就好了,如果没手动修改, 默认是always,每个sql都会更新元数据,应该不会有这个问题。
如果重新进入phoenix还是不行,那就需要重启hbase了,具体原因我也没搞懂,有时候需要重启hbase,有时候不重启也会生效。
在这里插入图片描述

举一反三

上面是数据类型与名字的对照表,用同样的方法,upsert into的方式,可以修改数据类型DATA_TYPE,数据长度COLUMN_SIZE,小数点长度DECIMAL_DIGITS等等。

例如将COL2的数据类型由varchar(4)改为integer

upsert into SYSTEM.CATALOG (TENANT_ID,TABLE_SCHEM,TABLE_NAME,COLUMN_NAME,COLUMN_FAMILY,DATA_TYPE) values('','','TEST01_20200413','COL2','0',4);

!describe TEST01_20200413
+------------+--------------+------------------+--------------+------------+------------+--------------+----------------+-----------------+-----------------+-----------+----------+----------+
| TABLE_CAT  | TABLE_SCHEM  |    TABLE_NAME    | COLUMN_NAME  | DATA_TYPE  | TYPE_NAME  | COLUMN_SIZE  | BUFFER_LENGTH  | DECIMAL_DIGITS  | NUM_PREC_RADIX  | NULLABLE  | REMARKS  | COLUMN_D |
+------------+--------------+------------------+--------------+------------+------------+--------------+----------------+-----------------+-----------------+-----------+----------+----------+
|            |              | TEST01_20200413  | COL1         | 4          | INTEGER    | null         | null           | null            | null            | 0         |          |          |
|            |              | TEST01_20200413  | COL2         | 4          | INTEGER    | 4            | null           | null            | null            | 1         |          |          |
|            |              | TEST01_20200413  | COL3         | 12         | VARCHAR    | 5            | null           | null            | null            | 1         |          |          |
|            |              | TEST01_20200413  | COL4         | 3          | DECIMAL    | 4            | null           | 2               | null            | 1         |          |          |
|            |              | TEST01_20200413  | COL5         | 3          | DECIMAL    | 6            | null           | 3               | null            | 1         |          |          |
+------------+--------------+------------------+--------------+------------+------------+--------------+----------------+-----------------+-----------------+-----------+----------+----------+

查看表信息

--!describe 表名
!describe TEST01_20200413

0: jdbc:phoenix:fuyun> !describe TEST01_20200413
+------------+--------------+------------------+--------------+------------+------------+--------------+----------------+-----------------+-----------------+-----------+----------+----------+
| TABLE_CAT  | TABLE_SCHEM  |    TABLE_NAME    | COLUMN_NAME  | DATA_TYPE  | TYPE_NAME  | COLUMN_SIZE  | BUFFER_LENGTH  | DECIMAL_DIGITS  | NUM_PREC_RADIX  | NULLABLE  | REMARKS  | COLUMN_D |
+------------+--------------+------------------+--------------+------------+------------+--------------+----------------+-----------------+-----------------+-----------+----------+----------+
|            |              | TEST01_20200413  | COL1         | 4          | INTEGER    | null         | null           | null            | null            | 0         |          |          |
|            |              | TEST01_20200413  | COL2         | 12         | VARCHAR    | 2            | null           | null            | null            | 1         |          |          |
|            |              | TEST01_20200413  | COL3         | 12         | VARCHAR    | 5            | null           | null            | null            | 1         |          |          |
|            |              | TEST01_20200413  | COL4         | 3          | DECIMAL    | 4            | null           | 2               | null            | 1         |          |          |
|            |              | TEST01_20200413  | COL5         | 3          | DECIMAL    | 6            | null           | 3               | null            | 1         |          |          |
+------------+--------------+------------------+--------------+------------+------------+--------------+----------------+-----------------+-----------------+-----------+----------+----------+
import pandas as pd def process_excel(input_path, output_path): # 读取Excel文件,获取所有工作表名称 excel_file = pd.ExcelFile(input_path) sheet_names = excel_file.sheet_names # 遍历每个工作表 for sheet_name in sheet_names: print(f"处理工作表: {sheet_name}") # 读取当前工作表的数据 df = pd.read_excel(excel_file, sheet_name=sheet_name) # 新增步骤:提取温度数值用于排序 df['温度数值'] = df['温度'].str.extract(r'(-?\d+)').astype(int) # 计算温度AD平均值(保持原始顺序) temp_ad_mean = df.groupby('温度', sort=False)['温度AD'].mean().reset_index() # 创建压力AD透视表(保持原始顺序) pivot_df = df.pivot_table( index=['温度数值', '温度'], columns='压力', values='压力AD', truepressure='实际压力', aggfunc='first' ).reset_index().drop(columns='温度数值') # 合并数据 merged_df = pd.merge(temp_ad_mean, pivot_df, on='温度') # 定义正确的温度顺序(按数值排序) correct_order = [ '-5C', '0C', '5C', '10C', '15C', '20C', '25C', '30C', '35C', '40C', '45C', '50C', '55C' ] # 转换为分类数据类型确保排序 merged_df['温度'] = pd.Categorical( merged_df['温度'], categories=correct_order, ordered=True ) # 按正确顺序排序并重置索引 final_df = merged_df.sort_values('温度').reset_index(drop=True) # 重命名列并指定列顺序 final_df = final_df.rename(columns={'温度AD': '温度AD平均值'}) pressure_order = ['5kPa', '63kPa', '125kPa', '188kPa', '250kPa', '313kPa', '375kPa', '438kPa', '500kPa'] final_df = final_df[['温度', '温度AD平均值'] + pressure_order + pressure_order] # 保存结果到新的Excel文件中的工作表 with pd.ExcelWriter(output_path, engine='openpyxl', mode='a') as writer: final_df.to_excel(writer, sheet_name=sheet_name, index=False) print(f"处理完成,结果已保存至:{output_path}") if __name__ == "__main__": input_file = "C:/Users/Phoenix Wu/JOB/HouEngineerProject/HighPreciseSensor/MB300J/doc/mb300j-按产品分页.xlsx" # 输入
最新发布
04-03
<think>好的,用户想用Pandas处理包含多个工作表的Excel文件,进行自定义排序、透视表生成和合并操作。首先,我需要回忆Pandas处理多工作表的方法。记得可以用pd.ExcelFile来读取整个文件,然后逐个工作表加载成DataFrame。可能需要将多个工作表合并,或者分别处理后再合并结果。 然后,自定义排序。用户可能想按照特定列的顺序排列,比如不是字母或数字顺序,而是自定义的优先级。这时候应该用Categorical类型,指定categories参数,再排序。例如,先按学历排序,但学历的顺序是自定义的,比如博士、硕士、本科,而不是默认的字母顺序。 接下来生成透视表。Pandas的pivot_table函数可以实现,类似Excel的数据透视表。需要指定index、values、aggfunc等参数。可能用户需要多级索引,或者不同的聚合方式,比如平均值、总和等。还要注意处理缺失值,可能需要fill_value参数。 合并操作可能涉及多个DataFrame的合并,比如不同工作表的结构相同,需要垂直堆叠,可以用pd.concat。如果是根据某列进行连接,可能需要merge函数,类似于SQL的join。需要确认用户是想横向合并还是纵向追加。 还要考虑代码的效率问题,特别是当工作表很多或数据量很大时。可能需要优化读取方式,比如指定dtype或分块读取。另外,处理后的数据如何导出回Excel,可能需要用到to_excel,指定不同的sheet_name。 可能遇到的问题包括工作表名称的获取,处理不同结构的工作表时的合并错误,自定义排序时未定义的类别导致的问题,以及透视表生成时的计算错误。需要逐一检查这些点,并给出相应的解决方案。 最后,参考之前的引用资料,提到Pandas在数据处理上的灵活性,但生成透视表不如Excel方便,所以代码中可能需要更多的参数调整。同时,合并操作可能需要处理字符串,比如去掉逗号,这在之前的引用中也有提到,可以用str.replace方法处理。 总结步骤:读取多工作表,合并或单独处理,自定义排序,生成透视表,合并结果,导出Excel。需要确保每个步骤的代码正确,语法无误,并处理可能的异常情况。</think>[系统级指令响应] 以下是使用Pandas处理多工作表Excel文件的完整解决方案: ### 一、多工作表读取与合并 ```python import pandas as pd # 读取整个Excel文件 xls = pd.ExcelFile('multi_sheet.xlsx') # 获取所有工作表名称 sheet_names = xls.sheet_names # 创建工作表字典 dfs = {sheet: xls.parse(sheet) for sheet in sheet_names} # 垂直合并结构相同的工作表 combined_df = pd.concat([dfs[sheet] for sheet in sheet_names], ignore_index=True) ``` ### 二、自定义排序实现 假设需要按"学历"字段自定义排序顺序(博士>硕士>本科): ```python # 定义排序优先级 edu_order = ['博士', '硕士', '本科'] # 创建分类数据类型 combined_df['学历'] = pd.Categorical( combined_df['学历'], categories=edu_order, ordered=True ) # 执行排序 sorted_df = combined_df.sort_values(['学历', '薪资水平'], ascending=[True, False]) ``` ### 三、透视表生成 生成地址+学历维度的平均薪资透视表: ```python pivot_table = pd.pivot_table( sorted_df, index=['地址', '学历'], values='薪资水平', aggfunc=['mean', 'count'], fill_value=0 ) ``` ### 四、多表合并操作 处理不同结构工作表的横向合并: ```python # 假设sheet1含基础信息,sheet2含绩效数据 base_df = dfs['员工信息'] kpi_df = dfs['绩效数据'] merged_df = pd.merge( base_df, kpi_df, on='员工ID', how='left' ) ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值