[英]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.