SymmetricDS PostgreSQL同步SQL Server时TIME数据类型转换失败求助
SymmetricDS 3.16单实例部署场景下,PostgreSQL主库的TIME类型字段(如sp_customer_open_from_am_tue值为09:30:00)同步到SQL Server从库时,被自动转换为带默认日期的Timestamp格式(1970-01-01 09:30:00.000),导致批量加载失败——SQL Server的TIME类型不接受包含日期的输入值,即使添加sendTimeAsDateTime=false参数也未解决。
1. 自定义类型映射规则
在从引擎(slave-001.properties)中添加类型映射配置,强制SymmetricDS对TIME类型进行精准匹配:
# 全局类型映射,指定TIME类型在源和目标库的映射关系 db.type.mapping=TIME=TIME target.db.type.mapping=TIME=TIME # 或针对具体数据库的精准映射 postgresql.db.type.mapping=TIME=TIME mssql.db.type.mapping=TIME=TIME
2. 调整PostgreSQL主库JDBC参数
修改主引擎(master-000.properties)的数据库连接URL,添加stringtype=unspecified参数,让PostgreSQL JDBC驱动以纯字符串形式返回TIME值,避免自动转为Timestamp:
db.url=jdbc:postgresql://postgresql:5432/testdb?stringtype=unspecified
3. 临时禁用批量加载(应急方案)
如果批量加载器的类型处理逻辑存在问题,可临时禁用批量加载,改用单条INSERT语句同步(注意:会降低同步性能,仅作临时排查或应急):
在slave-001.properties中添加:
bulk.load.enable=false
4. 自定义数据转换器(进阶方案)
若以上方法无效,可编写自定义Java转换器处理TIME字段格式,再通过SymmetricDS的转换规则配置生效:
步骤1:编写转换器类
import org.jumpmind.symmetric.io.data.transform.ITransformColumn; import org.jumpmind.symmetric.io.data.transform.TransformedData; import java.sql.Timestamp; import java.text.SimpleDateFormat; import java.util.Map; public class TimeTransform implements ITransformColumn { @Override public Object transform(TransformedData data, Map<String, String> parameters) { Object value = data.getSourceValue("sp_customer_open_from_am_tue"); if (value instanceof Timestamp) { // 提取Timestamp中的时间部分,转为SQL Server兼容的TIME字符串 Timestamp ts = (Timestamp) value; SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS"); return sdf.format(ts); } return value; } }
将编译后的.class文件放入SymmetricDS的lib目录。
步骤2:在主库配置转换规则
在PostgreSQL主库执行SQL,添加转换规则:
-- 创建转换表规则 INSERT INTO sym_transform_table (transform_id, source_table_name, target_table_name, transform_type, create_time, last_update_time) VALUES ('time_transform', 'myschema.mytable', 'mytable', 'custom', current_timestamp, current_timestamp); -- 绑定字段转换逻辑 INSERT INTO sym_transform_column (transform_id, source_column_name, target_column_name, transform_expression, transform_order, create_time, last_update_time) VALUES ('time_transform', 'sp_customer_open_from_am_tue', 'sp_customer_open_from_am_tue', 'com.yourcompany.TimeTransform', 1, current_timestamp, current_timestamp);
5. 验证目标库字段类型
确认SQL Server从库中目标字段确实为TIME类型,而非DATETIME或其他类型:
SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'mytable' AND COLUMN_NAME = 'sp_customer_open_from_am_tue';
修改配置后重启SymmetricDS服务,触发初始加载或数据变更,检查日志是否消除报错,同时查看SQL Server中的TIME字段值是否正确同步。
内容的提问来源于stack exchange,提问作者Pat

