数据导入时做字段类型转换时无效?UtilMethods.EnumToDictionary 返回

SqlSugar 处理完成
36 257
该叫什么 rookie 发布于1周前
悬赏:0 飞吻

在做数据ETL是,从源库读取数据到DataTable中后对目标库进行BulkCopy时,会根据DataTable的Column类型进行目标类型转换,如果源库与目标库是不同类型数据库,是否应该按目标库类型进行转换呢?我看代码中:

image.png

image.png

这里只是进行了小写转换,这个意义不大吧?感觉这里应该是要取值内建类型才对吧

image.png


因为现在的情况是,在BulkCopy时没有指定类型会按内容类型推断,这样有时就会出现推断失败从而造成导入失败的问题,请帮忙看一下


热忱回答36

  • 这个只是拿KEY VALUE ,没有拿特性的值

    0 回复
  • @fate sta:是的,但是不是应该拿特性的值才更合适呢?比如我现在的应用场景,我从Sql Server 迁出到 PGSql,采用无实体方式,数据类型依赖于导出数据的DataTable,目前这样就没办法去匹配目标数据库PGSql的类型,显然结果是不符合设计愿意的吧?所以是不是这里应该取特性的值会合适一点呢?

    0 回复
  • 0 回复
  • 这种是多最好的写法

    0 回复
  • 问题先别关闭呀!


    那目前我这种情况应该也是一种比较普遍常见的吧,而且从源代码与设计上看,应该也是按特性取值才是本意吧?这里不能修改吗,还是这里修改会引起其它什么相关问题呢?

    0 回复
  • @rookie: 直接发你有问题的业务代码,我上面的链接已经满足你需求了

    0 回复
  • 读出datatable结构 ->构造Type-> 字典转成构造的list<t>() ,在用 InseretByObject插入构造的Value

    0 回复
  • https://www.donet5.com/Ask/9/24996

    这个人应该和你一样的需求

    0 回复
  • https://www.donet5.com/Ask/9/26665


    业务代码很简单,源库是SqlServer 读取 ToDataTablePage,然后目标库是openGauss 写入 BulkCopy ,读取恰巧某一页时,数据内容有异样的就可能会引发失败,因为没有类型转换,它会自动根据数据内容进行设置,比如一页有5条数据,其中某个字段其实是double型,但前4条此值都是空值,只是第5条有数据,这样再写入这5条数据时就会引发异常:

    image.png

    0 回复
  • select 转一下类型

    0 回复
  • 查询时把类型转一下就行

    0 回复
  • @fate sta:是可以这样处理,查出来已经是一个datatable了,想怎样处理都行,我的意思是,是否需要框架支持一下呢?目前源代码看起来本意应该是想要做适配的,但因为源目标数据库不同所以它那个EnumToDictionary 并没有起到作业,看起来是感觉使用特性名称才对,否则中间的ColumnView这部分代码岂不是多余了吗?

    0 回复
  • @rookie:这个不是万能的,你直接转就能跑不作处理还是可能性不大的 

    这种情况需要你提供完整测试用例

    0 回复
  • 光说这个EnumToDictionary 我也不清楚你是什么情况

    0 回复
  • 如何复现

    0 回复
  • 关联库环境依赖确实不太好发测试代码,不过我感觉应该已经讲清楚了呀,根据上面的贴图与描述,就是在进行ColumnView类型数据时这个代码没有生效,因为那个PgSqlType这个字典没有取特性里的值,但DbColumnInfo的值是读取的数据库结构类似,它的DataType是对应的NpgsqlDbType 枚举特性里的值,所在感觉就是这块的问题,你看下呢?


    要测试也可以,源库sqlserver,目标库opengauss或pg应该都行,建一张表,设置某列double可为空,写5行数据,前4行此列保持null值,第5行写一个double值,然后应该就能复现了

    image.png

    0 回复
  • 好吧,特性是interal的,获取不到

    0 回复
  • @rookie:提供具体DEMO,我不清楚你讲的什么

    0 回复
  • 我的思维是从具体功能出什么问题,而不是你扔个源码给我。

    0 回复
  • 好的,具体问题就是在导入的时候报这个错,

    比如一页有5条数据,其中某个字段其实是double型,但前4条此值都是空值,只是第5条有数据,这样再写入这5条数据时就会引发异常:

    image.png

    原因就是 Npgsql 里会缓存 NpgsqlParameter,然后当第5行遇到值有数据值时,再进行write指定了double类型就失败了,

    我测试了下把这段代码注释掉目前就可以过去了,你这边看看是否需要处理吧

    image.png

    0 回复
  • @rookiehttps://www.donet5.com/Home/Doc?typeId=2366 提问模版,写个DEMO能重现的 ,解释不清楚

    0 回复
  • using SqlSugar;
    using System.Data;
     
    SqlSugarClient db = new SqlSugarClient(new List<ConnectionConfig>()
    {
        //new ConnectionConfig()
        //{
        //    ConfigId = "o",
        //    DbType = SqlSugar.DbType.SqlServer,
        //    ConnectionString = "Server=(local);uid=sa;pwd=sa;database=test;pooling=true;Max Pool Size = 2000;",
        //    IsAutoCloseConnection = true
        //},
        new ConnectionConfig(){
            ConfigId = "t",
            DbType = SqlSugar.DbType.OpenGauss,
            ConnectionString = "PORT=5432;DATABASE=testdb;HOST=127.0.0.1;PASSWORD=Gauss@1234;USER ID=postgres;No Reset On Close=true",
            IsAutoCloseConnection = true
        }
    });
     
    var tabName = "a_test_tab";
     
    var tgdb = db.GetConnection("t");
     
    //var omdb = db.GetConnection("o");
    //var pdt = omdb.Queryable(tabName, "c").ToDataTable();
     
    var pdt = MockDt();
     
    tgdb.Fastest<object>().AS(tabName).BulkCopy(pdt);
     
    //模拟源库数据表,dvalue列可为空类型
    DataTable MockDt()
    {
        var dt = new DataTable();
        dt.Columns.Add("dtext");
        dt.Columns.Add("dvalue"typeof(System.Double));
     
        //下面两行换下顺序则可成功写入
        dt.Rows.Add("r1", DBNull.Value);
        dt.Rows.Add("r2", 1000);
        return dt;
    }


    0 回复
  • 你好,请问有计划怎么处理或更新吗?如果有的话预期在哪个版本发布呢?

    0 回复
  • 1.3 BulkMerge (5.1.4.109)

    大数据 : 插入或者更新

    //原理
    //Oracle和SqlServer使用了Merge Into+BulkCopy
    //其他库底层是 db.Storageable(list).ExecuteSqlBulkCopy()
     
    db.Fastest<Order>().BulkMerge(List);
    db.Fastest<Order>().PageSize(100000).BulkMerge(List);
     
    //DataTable 升级到:SqlSugarCore 5.1.4.147-preview15+
    db.Fastest<System.Data.DataTable>()
            .AS("Order")//表名
            //第一个参数datatable
            //第二个参数主键
            //第三个参数是不是自增 true为自增
           .BulkMerge(dt, new string[] { "Id" },true);


    0 回复
  • System.InvalidOperationException:“Write for column 1 resolves to a different PostgreSQL type: OID 701 than the first row resolved to (OID 0). Please make sure to use clr types that resolve to the same PostgreSQL type across rows. Alternatively pass the same NpgsqlDbType or DataTypeName to ensure the PostgreSQL type ends up to be identical.”


    升级后还是这个提示,这里主要还是下面这里会造成前后类型不一致,这个value is double的判断是否还是去掉比较好呢?

    image.png

    0 回复
  • @rookie:这个需要提供完整DEMO ,这个也是因为某种情况加上去的不能去掉。需你提供DEMO

    0 回复
  • 上面DEMO代码就可以重现了呀?还要什么DEMO呢?

    就是现在主要的问题就是 里面的DbColumnInfo 是来自sql结果,外部我没有任何办法介入修改这个类型,如果value is double 那里不能修改,那看是否可以提供一个方法让我们外部可以进行设置那个column.Type 呢?我看源码里有获取一个EntityColumnInfo ,但最终没有使用它,是否可以利用一下呢?哪怕最终我放弃使用BulkCopy(DataTable), 使用 List<T> 的方式也可以呢

    image.png

    0 回复
  • @rookie: 提供完整能跑的DEMO,需要有建表语句,删掉OBJ和BIN打包上传

    0 回复
  • 0 回复
  • 你这个是SqlSugar.DbType.OpenGauss 不是PGSQL
    0 回复
  • 我处理一下

    0 回复
  • SqlSugarCore 5.1.4.157-preview01

    已处理 过五分钟勾一下预览

    0 回复
  • 可以通过了,但是需要这里两个地方都配置一下DbType是吗?感觉有些重复,只通过第一个DbType配置处理不行吗?

    image.png

    0 回复
  • @rookie:不需要配置 ,ORM会自动加的

    0 回复
  • image.png

    0 回复
  • 好的收到

    0 回复