무슨 일로 C 하셨습니까?

[C#]WPF::InfluxDB 본문

공부

[C#]WPF::InfluxDB

OJJJ 2021. 2. 25. 22:44

일을 하다보니 WPF에서 InfluxDB에 연결해서 데이터를 받아올 일이 생겼다.

 

MYSQL을 생각하며 조금 검색해보면 쉽게 구현할 줄 알았는데

 

죄다 영어글에 버전이 1.7이니 1.8이니 2.0이니 하는 바람에

 

정신이 혼미해졌다.

 

혹여라도 다음에 찾아볼 일이 있으니 글로 남겨본다.

 

( 참고로 이 글은 1.8버전이다 )

 


InfluxDB는 관계형 데이터베이스가 아닌 시계열 데이터 베이스로 어쩌구 저쩌구 자시구

하는 이야기는 넘어가고 기본만 알고가자

 

 

Inlfux Data Base MySQL
Bucket Database
Measurements Table
Tag-Key key
Field-Key key 아닌 놈들

 

이제 WPF에서 InfluxDB에 연결해서 데이터를 읽어보도록 하겠다.


 

시작은 관련된 API를 다운받아오는 것부터 시작이다.

 

무자비하게 [참조]를 오른쪽 버튼으로 눌러서 [NuGet 패키지 관리]를 눌러주자

 

InfluxDB.client를 검색해서 .Client.Client.Core를 다운받아주자.

 

사실 난 너무 여러 방식을 시도하는 바람에 관련된 패키지가 다 깔려있기 때문에 이거만 깔아도 되는지 모르겠다.

 

안되는거 같으면 influxDB 관련된 패키지는 다 다운받아보자

 


이제 코드로 작성해보자

 

public void f(){
	InfluxDBClient client = InfluxDBClientFactory.Create("http://127.0.0.1:8086",
    						"userid", "password".ToCharArray());
}

 

DB와 연결되서 작업을 수행할 Client 객체를 만든다. 객체를 생성한 것이지 아직 연결된 상태는 아니다.

 

useridpasswordinfluxDB에 접속하기 위한 계정으로 관리자 계정이면 userid"admin"을 넣으면 되겠다.

 

코드를 보면 알 수 있듯이 연결 자체가 http프로토콜을 사용하기 때문에

 

flux query문을 http에서 실행시킬 수 없다는 등의 에러가 발생할 수 있다. 그런 경우

 

*unix기준 (/etc/influxdb/influxdb.conf 파일)

 

config 파일, [http]항목에 "flux-enabled=true" 를 추가해주면 되겠다.

 

 

public async void f(){
	InfluxDBClient client = InfluxDBClientFactory.Create("http://127.0.0.1:8086",
    						"userid", "password".ToCharArray());
                            
    	string query = "";
	List<FluxTable> fluxTables = await client.GetQueryApi().QueryAsync(query, "org_id");
}
 

InfluxDB의 좋은점은 query문을 실행하기 위해 DB에 연결하고, 작업이 완료된 후 다시 연결을 해제하는 작업이 없어서 좋다. ( 내가 잘 몰라서 안하고 있는 것일 수도 있다 )

 

qeury와 함께 매개변수로 입력되는 "org_id"는 그룹 아이디 같은 느낌이 나는데 사실 아무거나 넣어도 잘 동작되서 뭔지 잘 모르겠다.

 


이제 query문을 살펴보자.

var query = $"from(bucket:\"database/autogen\") " +
            $" |> range(start: -15h)" +
            $" |> filter(fn: (r)=> r._measurement == \"table\")" +
            $" |> filter(fn: (r)=> r.column == \"data\" and r.colmun2 ==\"data2\")" +
            $" |> limit(n:1)";

그냥 MySQL에서 쓰는 query문을 사용하면 될 줄 알았는데 기가막히게 실행이 안된다.

 

방법을 찾다보니 flux query쓰면 실행이 된다.

 

' |> ' (파이프 꺽쇠?)기호는 뒤에 함수가 나온다는 것을 의미한다고 한다. 해당 기호를 안쓰고 함수를 쓰거나 해당 기호를 쓰고 뒤에 함수를 안쓰면 에러가 발생하니 그냥 코드 올려놓은 것처럼 쓰는게 문법 에러도 덜 나고 좋은 것 같다.

 

이제 헷갈리는게 막 나온다.

 

$"from(bucket:\"database/autogen\") " +

 

일단 앞서 알려주었듯 InfluxDB에서 databasebucket이라고 부른다.

 

신기한 점은 databaseflux query를 실행할 때 설정한다는 점이다.

그러므로 사용할 bucket을 위와같이 설정해주면 되겠다.

 

autogenretentionPolicy라고 database를 생성할 때 권한이 어쩌고 하는데 잘 모르겠다.

그냥 autogen 넣어줄면 잘 작동한다. 궁금하면 알아서 찾아보자.

 

그리고 influxDB에서 특정 데이터를 지칭할땐 쌍따옴표( " " ) 를 써줘야 한다.

 

그런데 문자열에서 쌍따옴표는 인식이 안되니 '\'을 써서 인식시켜줘야 한다. 

 

$" |> range(start: -15h)" +

 

range(start: n, stop: m) 함수는 불러올 데이터의 시작과 끝을 설정하는 함수이다

 

unixtimestamp를 직접 넣어줘도 되고 예문처럼 -15h(15시간 전)을 넣어줘도 된다.

 

센스가 있다면 -, h, m 등 무슨 키워드가 사용될지 알 것이다.

 

$" |> filter(fn: (r)=> r._measurement == \"table\")" +
$" |> filter(fn: (r)=> r.column == \"data\" and r.colmun2 ==\"data2\")" +

 

flux query에서 WHERE문 같은 함수이다.

 

일단은 measurement ( MySQL에선 table ) 조차도 하나의 key이기 때문에 읽고 싶은 measurement를 정하고 싶다면 위와 같이 지정해 주어야한다.

 

( 언더바( _ )가 붙은 key는 개발자가 만든 key가 아니라 자동으로 만들어지는 keymeasurement, field, vlaue같은 애들이 있다. )

 

+$" |> limit(n:1)";

limit함수는 MySQL과 크게 다르지 않다. 말 그대로 불러올 데이터의 갯수를 정하는 함수이다.


fluxTables.ForEach(table =>
{
	table.Records.ForEach(record =>
	{
		Console.WriteLine($"{record.GetTime()} {record.GetMeasurement()}: 
        		{record.GetField()} {record.GetValue()}");
	});
});

그럼 이제 받아본 데이터를 하나씩 찍어보면 된다. 

 

 

 

 

...
using InfluxDB.Client;
using InfluxDB.Client.Core.Flux.Domain;
using System;
using System.Collections.Generic;

public async void influxDB(){
	InfluxDBClient client = InfluxDBClientFactory.Create("http://127.0.0.1:8086",
    						"userid", "password".ToCharArray());
                            
  	var query = $"from(bucket:\"database/autogen\") " +
            $" |> range(start: -15h)" +
            $" |> filter(fn: (r)=> r._measurement == \"table\")" +
            $" |> filter(fn: (r)=> r.column == \"data\" and r.colmun2 ==\"data2\")" +
            $" |> limit(n:1)";
            
	List<FluxTable> fluxTables = await client.GetQueryApi().QueryAsync(query, "org_id");
    
    	fluxTables.ForEach(table =>
	{
		table.Records.ForEach(record =>
		{
			Console.WriteLine($"{record.GetTime()} {record.GetMeasurement()}: 
        			{record.GetField()} {record.GetValue()}");
		});
	});
    	client.Dispose();
}

최종 코드이다. 잘 작동하는지 확인해보자.

'공부' 카테고리의 다른 글

[Android Studio:Java]백그라운드 서비스  (3) 2021.10.11
Visual Studio 프로젝트 GitHub에 올리기  (0) 2021.02.15
MongoDB::NoSQL?  (0) 2021.01.22
Comments