簡體   English   中英

使用 c# 將 csv 文件數據插入控制台應用程序中的 clickhouse 數據庫

[英]insert the csv file data into clickhouse database in the console application using c#

我需要使用 c# 將 csv 文件數據插入到控制台應用程序中的 clickhouse 數據庫中。在 sql 數據庫中,數據正在添加到表中,而在 clickhouse 中,它沒有將數據添加到表中。

數據無法添加到 clickhouse 數據庫中,我也沒有收到任何錯誤

    static void Main()
    {
        string csv_file_path = @"C:\Users\thummala.naveen\Downloads\Employee.csv";
       
      InsertDataIntoSQLServerUsingSQLBulkCopy();

    }
    
    public static void InsertDataIntoSQLServerUsingSQLBulkCopy()
    {

        
        SqlConnection con = new SqlConnection(@"data source=10.1.230.49\standard2019;initial catalog=thummala.naveen@hcl.com;uid=sa;password=dbnms#123;integrated security=false;MultipleActiveResultSets=True;App=EntityFramework");
        
        string filepath = "C:\\Users\\thummala.naveen\\Downloads\\Employee.csv";
        StreamReader sr = new StreamReader(filepath);
        string line = sr.ReadLine();
        string[] value = line.Split(',');
        DataTable dt = new DataTable();
        DataRow row;
        foreach (string dc in value)
        {
            dt.Columns.Add(new DataColumn(dc));
        }

        while (!sr.EndOfStream)
        {
            value = sr.ReadLine().Split(',');
            if (value.Length == dt.Columns.Count)
            {
                row = dt.NewRow();
                row.ItemArray = value;
                dt.Rows.Add(row);
            }
        }
        
        ClickHouse.Client.ADO.ClickHouseConnection conn = new ClickHouse.Client.ADO.ClickHouseConnection(@"Compress=True;CheckCompressedHash=False;Compressor=lz4;Host=10.1.162.59;Port=8123;User=default;Password=clickhouse@123;SocketTimeout=600000;Database=naveentest;");
        ClickHouseBulkCopy bcs = new ClickHouseBulkCopy(conn.ConnectionString);
        bcs.DestinationTableName = "Emp";
        bcs.BatchSize = dt.Rows.Count;
        using var csvs = CsvDataReader.Create("C:\\Users\\thummala.naveen\\Downloads\\Employee.csv");

        bcs.WriteToServerAsync(csvs);
        conn.Close();
    }



}

}

雖然這在技術上不是一個答案,但這應該可以幫助您自己找到問題:在單元測試框架中重寫您的代碼將非常容易測試。 我可以推薦 xunit 嗎? 但是任何單元測試框架都可以。

該結構並不完美,但應該會引導您走上正確的道路,使您的代碼更易於測試。 (因此更容易調試)

通過這種結構,您可以將您的個人行為“模擬”(即 moq 框架),並編寫覆蓋率測試和白盒測試,並准確地指出您的問題所在。

對於你的主要方法 class,默認名稱程序,我想這會做:

using System.Data;

namespace StackDemoConsoleApp
{
    public class Program
    {
        private static readonly IRowCountHandler _rowCountHandler = new RowCountHandler(new EmployeeFileHandler(), new DataTablePopulator(), new DataTablePreparer());
        private static readonly IPersistenceWriter _persistenceWriter = new PersistenceWriterClickHouse();

        public static void Main(string[] args)
        {
            DataTable dataTableForRowCount = _rowCountHandler.FindRowCount();
            _persistenceWriter.WriteToPersistence(dataTableForRowCount);
        }
    }
}

其中 rest 是接口或類,您應該在項目資源管理器中為其單獨命名文件:

    using System.Data;
    using System.IO;
    
    namespace StackDemoConsoleApp
    {
        public class DataTablePopulator : IDataTablePopulator
        {
            public DataTable PopulateDataTable(StreamReader streamReader, ref string[] value, DataTable dataTableForRowCount)
            {
                while (!streamReader.EndOfStream)
                {
                    value = streamReader.ReadLine().Split(',');
                    if (value.Length == dataTableForRowCount.Columns.Count)
                    {
                        var row = dataTableForRowCount.NewRow();
                        row.ItemArray = value;
                        dataTableForRowCount.Rows.Add(row);
                    }
                }
    
                return dataTableForRowCount;
            }
        }
    }


    using System.Data;
    
    namespace StackDemoConsoleApp
    {
        public class DataTablePreparer : IDataTablePreparer
        {
            public DataTable PrepareDataTableStructure(string[] value)
            {
                DataTable dataTableForRowCount = new DataTable();
                foreach (string dc in value)
                {
                    dataTableForRowCount.Columns.Add(new DataColumn(dc));
                }
    
                return dataTableForRowCount;
            }
        }
    }


    using System.IO;
    
    namespace StackDemoConsoleApp
    {
        public class EmployeeFileHandler : IEmployeeFileHandler
        {
            public void ReadEmployeeFile(out StreamReader sr, out string[] value)
            {
                string filepath = "C:\\Users\\thummala.naveen\\Downloads\\Employee.csv";
                sr = new StreamReader(filepath);
                string line = sr.ReadLine();
                value = line.Split(',');
            }
        }
    }

    using System.Data;
    using System.IO;
    
    namespace StackDemoConsoleApp
    {
        public interface IDataTablePopulator
        {
            DataTable PopulateDataTable(StreamReader sr, ref string[] value, DataTable dataTableForRowCount)
        }
    }


using System.Data;
using System.IO;

namespace StackDemoConsoleApp
{
    public interface IDataTablePopulator
    {
        DataTable PopulateDataTable(StreamReader sr, ref string[] value, DataTable dataTableForRowCount)
    }
}

using System.IO;

namespace StackDemoConsoleApp
{
    public interface IEmployeeFileHandler
    {
        void ReadEmployeeFile(out StreamReader sr, out string[] value);
    }
}

using System.Data;

namespace StackDemoConsoleApp
{
    public interface IPersistenceWriter
    {
        void WriteToPersistence(DataTable dataTableForRowCount);
    }
}

using System.Data;

namespace StackDemoConsoleApp
{
    public interface IRowCountHandler
    {
        DataTable FindRowCount();
    }
}

using System.Data;

namespace StackDemoConsoleApp
{
    public class PersistenceWriterClickHouse : IPersistenceWriter
    {
        public void WriteToPersistence(DataTable dataTableForRowCount)
        {
            ClickHouse.Client.ADO.ClickHouseConnection conn = new ClickHouse.Client.ADO.ClickHouseConnection(@"REDACTED");
            ClickHouseBulkCopy bcs = new ClickHouseBulkCopy(conn.ConnectionString);
            bcs.DestinationTableName = "Emp";
            bcs.BatchSize = dataTableForRowCount.Rows.Count;
            using var csvs = CsvDataReader.Create("C:\\Users\\thummala.naveen\\Downloads\\Employee.csv");
            bcs.WriteToServerAsync(csvs);
            conn.Close();
        }
    }
}

using System.Data;
using System.IO;

namespace StackDemoConsoleApp
{
    public class RowCountHandler : IRowCountHandler
    {
        private readonly IEmployeeFileHandler _employeeFileHandler;
        private readonly IDataTablePreparer _dataTablePreparer;
        private readonly IDataTablePopulator _dataTablePopulator;

        public RowCountHandler(IEmployeeFileHandler employeeFileHandler, IDataTablePopulator dataTablePopulator, IDataTablePreparer dataTablePreparer)
        {
            _employeeFileHandler = employeeFileHandler;
            _dataTablePopulator = dataTablePopulator;
            _dataTablePreparer = dataTablePreparer;
        }

        public DataTable FindRowCount()
        {
            StreamReader sr;
            string[] value;
            _employeeFileHandler.ReadEmployeeFile(out sr, out value);
            DataTable dataTableForRowCount= _dataTablePreparer.PrepareDataTableStructure(value);
            return _dataTablePopulator.PopulateDataTable(sr, ref value, dataTableForRowCount);
        }
    }
}

在這個結構中,fx。 很容易看出: SqlConnection con = new SqlConnection(@"redacted");

什么也沒做。

代碼現在更易於閱讀和理解。

由於代碼現在被拆分成更小的方法,因此您尋求幫助要容易得多,因為您向其他人展示的代碼庫要小得多,並且更專注於實際問題。

以這種方式編寫的代碼實際上有更多的好處,而不僅僅是這樣。 但是這篇文章已經太長了。

需要明確的是,我遺漏了大量的重命名,因為說真的,我懶得去更正它。 這段代碼中有太多“不要做”......

但是請通過 DI、SOLID 和 Clean Code 使您的代碼可測試。

這將使您的代碼質量更好,使其他人能夠更快地幫助您,幫助您自己,理解和調試您自己的代碼,並使您的代碼可測試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM