[ php ] csv 파일 테이블로 import 하기 ( LOAD DATA INFILE )





디렉토리에 들어있는 csv 파일들을 DB에 저장할 일이 생겼다.

파일 개수가 많아 php로 파일 리스트를 읽어 테이블들로 일괄 저장하려고 한다.

 

mysqlimport도 생각해봤는데 LOAD DATA INFILE 문 처리속도가 더 빠르다고 한다.

 

일단 DB에 접속하자.

 

$conn = mysqli_connect('localhost', 'userid', 'password','dbname');
if (mysqli_connect_errno($conn)) 
     echo "데이터베이스 연결 실패: " . mysqli_connect_error();
else
 echo "connection success";

 

csv파일을 import할 테이블도 생성하자.

기존 csv파일에 없는 idx필드를 생성해 primary key값으로 설정하고 자동 증가 옵션을 주었다.

 

$sql = "CREATE TABLE `테이블이름` (
     `idx` INT(11) NOT NULL AUTO_INCREMENT,
     PRIMARY KEY(idx),
     `날짜` INT(8) NOT NULL,
     `가격` INT(5) NOT NULL,
     ...

`시간` INT(4) NOT NULL 
 )";

 

if(mysqli_query($conn, $sql))

    echo "Table created successfully"; 

else
    echo "Error creating table:".mysqli_error($conn);
  

 

LOAD DATA INFILE 구문 규칙은 아래와 같다.

 

LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name' [REPLACE | IGNORE] INTO TABLE tbl_name [CHARACTER SET charset_name] [{FIELDS | COLUMNS} [TERMINATED BY 'string'] [[OPTIONALLY] ENCLOSED BY 'char'] [ESCAPED BY 'char'] ] [LINES [STARTING BY 'string'] [TERMINATED BY 'string'] ] [IGNORE number LINES] [(col_name_or_user_var,...)] [SET col_name = expr,...]

[각주:1]

 

기본적으로 csv 파일 이름과 테이블 이름만 입력해도 사용 가능하다.

이럴 경우 나머지 옵션들은 기본 옵션으로 실행되게 된다.

 

파일 이름은 경로와 함께 나타낼 수 있으며 상대 경로 절대 경로 다 사용 가능하다.

기본적으로 현재 데이터베이스가 있는 디렉토리가 기본 경로가 된다.

csv파일이 데이터베이스와 다른 경로에 있기 때문에 절대 경로로 나타낸다.

필드가 , 로 구분되어 있기 때문에 FIELDS TERMINATED BY ',' 옵션을 추가했다.

 

참고로 기본 필드 값은 아래와 같다.

 

FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\'
LINES TERMINATED BY '\n' STARTING BY ''

 

 

응용프로그램에서 생성되는 많은 csv파일이 아래와 같은 포맷을 사용한다고 하니 참고하자.

 

LOAD DATA INFILE 'data.txt' INTO TABLE tbl_name
  FIELDS TERMINATED BY ',' ENCLOSED BY '"'
  LINES TERMINATED BY '\r\n'
  IGNORE 1 LINES;

 

 

csv파일의 첫 라인에는 필드 이름이 있었기 때문에 IGNORE 1 LINES"; 옵션도 추가했다.

IGNORE N LINES 옵션은 파일 N번째 라인부터 테이블로 저장하게 한다.

 

만약 테이블의 필드와 csv파일의 필드가 정확히 일치하면 그냥 아래와 같이 적어주면 된다.

 

$sql = "LOAD DATA INFILE '/var/lib/mysql-files/파일이름.csv'
     INTO TABLE `테이블이름`
     FIELDS TERMINATED BY ','
     IGNORE 1 LINES";
  

 

간혹 파일이 존재하는데 파일이 없다는 에러가 나올 수 있다. 



mysql> LOAD DATA INFILE '/home/changelist.csv' INTO TABLE changelist

    ->   FIELDS TERMINATED BY '\t'

    ->   IGNORE 1 LINES;

ERROR 29 (HY000): File '/home/changelist.csv' not found (Errcode: 13)



그럴 경우는 주로 권한의 문제로 파일이 있는 폴더나 파일 소유자를 mysql로 변경하면 해결 된다. 


chown mysql:mysql changelist.csv


 

그런데 나는 인덱스 필드를 추가했기 때문에 ( ) 옵션으로 필드들 이름을 하나하나 적어주기로 한다(...)

여기서 필드들 이름 순서는 파일에 나타나는 필드  순서와 동일해야 한다.


$sql = "LOAD DATA INFILE '/var/www/html/파일이름.csv'
     INTO TABLE `테이블이름`
     FIELDS TERMINATED BY ','
     IGNORE 1 LINES"

     (`날짜`,`가격`,... ,`시간`)";

 

if(mysqli_query($conn, $sql))
    echo "LOAD DATA INFILE successfully"; 
else
    echo "Error LOAD DATA INFILE:".mysqli_error($conn);

 

$conn->close();

 


필드 명까지 다 입력하고 php 파일을 실행하자 테이블이 생성되고 csv 파일이 테이블로 잘 변환된 것을 확인할 수 있었다 : )

 

만약 테이블에 null 값을 입력해야 한다면 (그리고 csv 파일에는 빈 입력값으로 들어있다면) 

빈 입력값을 \N으로 입력해야 한다



MySQL manual says:


When reading data with LOAD DATA INFILE, empty or missing columns are updated with ''. If you want a NULL value in a column, you should use \N in the data file. The literal word “NULL” may also be used under some circumstances.

So you need to replace the blanks with \N like this:


예시: 

1,2,3,4,5

1,2,3,\N,5

1,2,3



 

 

  1. 출처:http://dev.mysql.com/doc/refman/5.1/en/load-data.html [본문으로]
  • 2017.03.30 13:40 ADDR 수정/삭제 답글

    비밀댓글입니다

    • adana 2017.03.30 21:28 신고 수정/삭제

      네 이메일주소 알려주세요

[ php ] mysql / mysqli - select / insert / update 문 사용 예시

 

 

1. DB 연결하기


$conn = mysqli_connect('localhost', 'username', 'password','dbname');
if (mysqli_connect_errno($conn))
{
  echo "데이터베이스 연결 실패: " . mysqli_connect_error();
}
else
{

// to do something

}

 


2. select 문 사용


mysql_query 결과로 영향받은 row수를 알기 위해서는 mysqli_affected_rows 함수를 사용한다. 

- select 결과를 associative array로 반환받기 

$check_query = "SELECT * from ".$table." where code='".$code."' and period='".$period."'";

 $result=mysqli_query($conn,$check_query);

if(mysqli_affected_rows($conn) > 0)
{

  

 // mysqli_fetch_assoc 함수 

 // Fetch a result row as a numeric array and as an associative array:


 while ($row = mysqli_fetch_assoc($result))
 {
            $id = $row['id']."\t";
            $name = $row['name']."\t";
            $news .= $row['news'];

  }
                                 

}

mysqli_free_result($result);


 참고: http://www.w3schools.com/php/func_mysqli_fetch_array.asp

- sum 함수를 사용한 select 문 예시 


 $sum_query = "select Sum(`scores`) as value_sum from tablename";
        $result = $conn->query($sum_query);
        $row = mysqli_fetch_assoc($result);
        $sum_up_short = $row['value_sum'];



참고: http://www.tizag.com/mysqlTutorial/mysqlsum.php

3. insert 문 사용

$query = "INSERT INTO ".$table."(code, name_kor,name_eng, market, type, period,`".$field."`) VALUES ('".$code."','".$name_kor."','".$name_eng."','".$market."','".$type."','".$period."','".$value."');";

   if(mysqli_query($conn, $query))
       echo "insert successfully";
      else
       echo "Error:".$query."mesage:".mysqli_error($conn);  

3. update 문 사용

 $query = "UPDATE ".$tablename." SET `field0`='".$value0."' ,`field1`='".$value1."' ,`field2`='".$value2."' ,`".$field3."`='".$value3."' WHERE 날짜='".$time."' AND 종목코드='".$stockcode."'";
    
    if(mysqli_query($conn, $query))
       echo "update successfully";
      else
       echo "Error:".$query."mesage:".mysqli_error($conn);  
       

 

 4. DB 연결 닫기 

$conn->close();



 

DB connectin error - Authentication with old password no longer supported, use 4.1 style passwords




C# 프로그램에서 mysql에 접속하여 사용하고 있는데 

어느순간 아래와 같은 메세지가 뜨면서 접속이 안되는 현상이 발생하였습니다. 


에러 메세지 : Authentication with old password no longer supported, use 4.1 style passwords

에러가 나는 DB 접속문: MySqlConnection conn = new MySqlConnection("SERVER=***.***.com;DATABASE=**;UID=**;PWD=****;");



mysql 4.1 버전부터 PASSWORD() 함수가 

기존에는 16비트 해쉬값을 사용하였으니 41비트 해쉬값을 생성하도록 변경되었습니다.


에러 메세지에 따라 접속하는 유저의 암호를 새로운 해쉬값으로 생성하도록 아래와 같이 작업하였습니다. 

(그런데 닷넷 connector 업뎃도 안한것 같은데 왜 갑자기 에러가;)


해결방법


// 리눅스에서 mysql console에 접속
#mysql -u root -p

// 예전 16비트 해쉬값을 사용하지 않도록 old_passwords 시스템변수를 0으로 변경한다 
// 참고:https://dev.mysql.com/doc/refman/5.0/en/password-hashing.html 
mysql> SET old_passwords=0;

// 해당 username의 password를 41비트 해쉬값으로 변경한다. 
// 예시 SET PASSWORD FOR root=PASSWORD('1234');
mysql> SET PASSWORD FOR username=PASSWORD('password');


or (호스트 명시할때)

// 해당 host의 username의 password를 41비트 해쉬값으로 변경한다. 
mysql> SET PASSWORD FOR user@host = PASSWORD('password');



[ 안드로이드 어플 만들기 ] 3. 실제 디바이스에서 테스트 하기



이전글: [ 안드로이드 어플 만들기 ] 2. 프로젝트 생성하기 


참고: http://developer.android.com/tools/device.html


삼성 통합 usb driver 다운로드 사이트:

http://local.sec.samsung.com/comLocal/support/down/kies_main.do?kind=usb




이번 포스팅에서는 앞의 포스팅에서 생성된 hello world 프로젝트를 

실제 안드로이드 디바이스에서 실행해 보겠습니다. 


안드로이드 디바이스를 사용하려면 아래 설정들이 필요합니다. 


1. SDK에서 Google USB Driver 설치

2. 디바이즈 제조사에 맞는 USB 드라이버 설치

3. 휴대폰에서 USB 디버깅 활성화 



 위 설정들을 차례대로 세팅해보도록 하겠습니다. (환경 : 갤럭시 s 4) 


메뉴에서 Tools - Android - SDK mangager를 열어 google USB driver 설치를 확인합니다.





혹 설치가 안되어 있다면 Google USB DRiver를 체크하고 패키지를 설치하도록 합니다. 

 

다음으로 자신의 휴대폰의 usb driver를 다운받아 설치하도록 합니다. 


참고로 삼성 통합 usb driver 다운로드 사이트는 아래와 같습니다.

http://local.sec.samsung.com/comLocal/support/down/kies_main.do?kind=usb



마지막으로 휴대폰에서 USB 디버깅 활성화를 하기 위해 

스마트폰에서 환경설정 - 더보기 - 디바이스 정보로 들어갑니다. (갤럭시 S4 기준)







디바이스 정보에서 빌드 번호를 연이어 7번 클릭하고 전 화면으로 돌아가면  

아래와 같이 개발자 옵션이 활성화 되어있는 것을 확인할 수 있습니다.






개발자 옵션으로 들어가서 USB 디버깅 기능을 체크하고 

확인을 누릅니다. 




이제 모든 준비가 끝났습니다. 


다시 안드로이드 스튜디오로 돌아가서 어플리케이션을 실행시킵니다. 





위 메뉴에서 ▶ 버튼을 누르면 어플리케이션을 디바이스에서 실행할 것인지

에뮬레이터에서 실행할 것인지 아래와 같이 결정을 해야합니다. 


디바이스에서 실행을 하려고 하는데 현재 상태가 오프라인으로 뜨면서 제대로 실행히 안 됩니다. 





구글링을 해보니 이럴 경우에는 스마트폰 재시작을 하라고(...) 해서 

스마트폰 재시작을 하고 다시 usb로 연결하니 아래와 같이 

USB 디버깅을 허용 요청이 와서 허용을 하였습니다. 






다시 안드로이드 스튜디오로 갔더니 이제 디바이스 상태가 

정상적으로 온라인으로 나타납니다. 





OK를 누르자 휴대폰에 헬로우 월드 화면이 나오면서 

정상적으로 실행 결과를 확인할 수 있었습니다. 





이제 휴대폰으로 어플의 실행 결과를 직접 확인해볼 수 있게 되었습니다 : )



[ 안드로이드 어플 만들기 ] 2. 프로젝트 생성하기


이전글: [ 안드로이드 어플 만들기 ] 1. 앱 개발 환경 구축 


참고: https://developer.android.com/training/basics/firstapp/index.html


이번 포스팅에서는 안드로이드 어플 프로젝트 생성과 기본 파일에 대한 설명을 하겠습니다. 

 기본적으로 안드로이드 개발자 홈페이지의 tutorial을 참고로 하였습니다. 



application name만 변경하고 나머지는 기본 설정으로 진행합니다. 

package name은 자바의 기본 네이밍 방식을 따르며 

안드로이드 시스템 전체에서 유일한 이름이야 합니다. 




minimum SDK는 어플이 어느 예전 버전의 안드로이드까지 제공하는지를 결정합니다. 

어플에서 다양한 기기들을 지원하게 하려면 어플이 사용해야 하는 주요 기능을 제공하는 API중 

가장 낮은 버전을 사용해야 합니다. 

자동으로 설정된 API 15를 사용하면 90.4%의 기기가 호환된다는 설명이 있어 

변경하지 않고 진행합니다. 





그 외 파일 이름은 변경하지 않고 그대로 진행하여 프로젝트가 생성이 되었습니다.




 






프로젝트 생성을 끝내자 Gradle build가 자동으로 실행이 되면서

activity_main.xml 파일에서 기본으로 들어있던 hello world가 preview에서 보이는 것을 확인할 수 있습니다. 

아래는 기본적인 파일들에 대한 설명입니다. 




AndroidManifest.xml 

어플리케이션에 관한 정보들이 설정되어 있습니다.

어플리케이션 라벨, 아이콘, 액티비티 라벨, 처음 실행될 액티비티명,  

또한 어플리케이션이 실행될 때 필요한 권한 등이 명시되어 있습니다. 


MainActivity.java

어플리케이션을 구성하는 액티비티를 구현하는 자바 클래스이며

어플리케이션 실행 시, 최초에 실행되는 자바 클래스입니다.

클래스 이름은 변경 가능합니다. 


activity_main.xml

액티비티 실행시 화면에 나타나는 레이아웃을 설계하는 파일입니다.

안드로이드 스튜디오는 이 파일을 파일 내용을 preview UI 로 보여주는 기능도 있어 

레이아웃 변경시 프리뷰에서 곧바로 확인이 가능합니다.  


res 폴더

 앱을 만들 때 사용할 리소스들(문자열, 사진등)을 저장하는 폴더입니다.








build.gradle(Module: app)

앱을 빌드할 때 사용하는 파일입니다. 

defaultConfig 및 빌드시 사용할 dependency 정보를 포함하고 있습니다. 

아래 파일 내용을 보면서 좀 더 자세히 확인해보겠습니다.



apply plugin: 'com.android.application'


android {
compileSdkVersion 21
buildToolsVersion "21.1.1"

defaultConfig {
applicationId "com.example.administrator.stocknews"
minSdkVersion 15
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.3'
}


compileSdkVersion

앱을 컴파일할때 사용할 sdk버전으로

기본적으로 설치되어 있는 sdk에서 가능한 안드로이드의 가장 최신버전으로 설정됩니다. 


applicationID

프로젝트를 생성할 때 첫 단계에서 만들었던 패키지 이름입니다.


minSdkVersion

프로젝트 생성할 때 설정했던 어플에서 지원가능한 SDK의 가장 낮은 버전 입니다.


targetSdkVersion

어플에서 지원가능한 SDK의 가장 높은 버전입니다.

안드로이드에서 새로운 버전이 나오면 어플을 새로운 버전에서 테스트 후 문제 없으면

이 값을 업데이트하여 가장 최신 버전의 새로운 기능등을 사용하도록 합니다. 









  • 2018.02.04 07:13 ADDR 수정/삭제 답글

    비밀댓글입니다

    • adana 2018.02.10 11:55 신고 수정/삭제

      옷 감사합니다 님도 로또 되세요! ;)

[ 안드로이드 어플 만들기 ] 1. 앱 개발 환경 구축





앱 개발 환경 구축


1. JDK 다운로드 & 설치


http://www.oracle.com/technetwork/java/javase/downloads/index.html


위 사이트에서 가장 최근의 JDK를 다운받는다. 

윈도우는 사용하는 시스템 종류에 따르 실행파일을 선택한다. 

윈도우 64비트 실행파일을 받아 설치 완료

 



설치 후 자바 패스 설정은 아래 포스팅 참조

 

http://kugancity.tistory.com/entry/윈도우와-elipse-자바-패스-설정



2. 안드로이드 스튜디오 설치하기 

 

아래 안드로이드 사이트에서 tool탭을 눌러 안드로이드 개발 툴을 다운받는다. 



https://developer.android.com/sdk/index.html







분명히 저번 주 쯤에 사이트에 들어갔을 때는 

위와 같이 Eciplse ADK가 메인에 있어 ADK로 개발 환경 세팅을 하고 

오늘 포스팅을 하기 위해  다시 사이트에 들어갔더니 

공식 툴이 안드로이드 스튜디오로 변경이 되었다고 한다 -_-;;;


안드로이드는 개발 환경 변화가 많다고 하는 말이 새삼 실감이 된다.  

공식 툴이 변했다고 하니 다시 안드로이드 스튜디오를 다운받아 설치를 진행했다. 











중간에 선택 과정도 없이 그냥 클릭 클릭하다가

마지막 단계에서만 처음 개발하는 것이라 아래 선택지를 선택하고 설치 완료하였다. 







그 후 자동으로 set up과정도 끝나고 android studio의 첫 화면이 나타났다. 


시험삼아 새 안드로이드 프로젝트 생성을 선택하였다. 









그냥 기본 세팅 그대로 했더니 아래와 같이 개발 환경 창이 나타났다. 

코드가 실행되는 것을 곧바로 확인할 수 있어서 더 좋은 것 같다. 




다음 포스팅에는 간단한 프로젝트를 실제로 만들어보겠다. 






















 

 

 


  • CDE 2015.01.11 16:32 ADDR 수정/삭제 답글

    다음 편도 빨리 나오길 기대합니다.

    • adana 2015.01.13 00:50 신고 수정/삭제

      찾아주셔서 감사합니다. 다음편은 곧 올리도록 하겠습니다 +_+

  • OH 2015.01.20 22:55 ADDR 수정/삭제 답글

    저도 다음 편이 기대됩니다^^

MySQL - select 구문 사용 예시

 

MySQL - select 구문 사용 예시

 

자주 사용하는 select 구문을 정리해 보았다.

 

 전체 필드 선택

 

예시 ) 특정 테이블의 전체 필드들을 가져온다.

 

SELECT * from `tablename`

 

 

- 가져올 필드를 지정 

   테이블 이름과 필드 이름은 `로 감싼다. 필드 이름들은 , 로 나열한다.

 

예시 )  field1, field2 만 선택

 

SELECT `field1` , `field2`
FROM `tablename`

 

 

 

- 가져올 조건을 지정 , 필드의 값은 '로 감싼다

 

예시 ) 한개의 필드 값 지정, = 은 exact matching으로 필드 값이 정확히 value와 같아야 데이터를 가져온다.

SELECT * from `tablename`  WHERE `field`='value'

 

예시 ) 한개의 필드 값 지정, LIKE는 부분 일치 조건으로 %위치에는 빈 값도 포함하여 아무 값이나 올수 있다. 정규식의 *와 같다. 

- 회사 이름이 우선주로 끝나는 데이터들 가져오기  

SELECT * FROM tablename WHERE `회사이름` LIKE '%우선주'

 

- 회사 이름이 우선주로 시작하는 데이터들 가져오기  

SELECT * FROM tablename WHERE `회사이름` LIKE '우선주%'

 

- 회사 이름에 우선주가 들어가는 데이터들 가져오기  

SELECT * FROM tablename WHERE `회사이름` LIKE '%우선주%'

 

 

예시 ) 두개의 필드 값을 AND로 지정

- 특정 날짜의 종목코드에 대한 정보를 테이블에서 가져오기

SELECT * from `tablename` WHERE 날짜='2014-06-11' AND 종목코드='A068400'

 

예시 ) 조건 필드 값을 AND와 OR로 지정, 같이 처리되어야 하는 조건을 ( )로 묶는다.

코스피와 코스닥에서 우선주 종목들의 정보를 한번에 가져오기 위해 아래와 같은 조건을 사용하였다.

SELECT * FROM tablename WHERE `회사이름` LIKE '%우선주%' AND ( `market` = '유가증권시장상장' OR `market` = '코스닥시장상장' ) ;


예시) 기간을 지정

SELECT * FROM tablename where Date >= '2011/02/25' and Date <= '2011/02/27'

 

 

- 가져온 데이터를 정렬한다

 

 예시 ) 가져온 필드들을 최신 날짜 순으로 정렬

 

SELECT `field1` , `field2`
FROM `tablename`
WHERE `field` = 'value'
ORDER BY `날짜` DESC

 

예시 ) 가져온 필드들을 오래된 날짜 순으로 정렬

SELECT DISTINCT `날짜`
FROM tablename
ORDER BY `날짜` ASC

 

예시 ) 가져온 필드들을 최신 날짜 순으로 정렬해서 특정 개수만큼 가져오도록 지정

LIMIT num1, num2 : 행 num1부터 num2개수 만큼 가져오기.

아래 예시는 가장 최근 날짜 데이터부터 30개만 가져오도록 지정

 

SELECT `field1` , `field2`
FROM `tablename`
WHERE `field1` = 'value'
ORDER BY `날짜` DESC
LIMIT 0 , 30

 

 

 

- 특정 필드에서 unique 값만 가져온다

 

예시 ) market 필드에서 유일한 값들만 가져온다.

SELECT DISTINCT `market` FROM tablename;

 

 

 

 

 

 

  • 2014.11.08 11:54 ADDR 수정/삭제 답글

    비밀댓글입니다

php.ini 수정 - upload_max_filesize, memory_limit, post_max_size 증가

 

 

 

phpMyAdmin에서 외부 Mysql DB를 가져오기 하기 할떄 아래와 같은 메세지가 나왔다.

 

 너무 큰 파일을 업로드하려고 시도했습니다. 제한을 해결하기 위해서는 documentation를 참조하여 주십시오.

 

 

Starting with version 2.7.0, the import engine has been re–written and these problems should not occur. If possible, upgrade your phpMyAdmin to the latest version to take advantage of the new import features.

The first things to check (or ask your host provider to check) are the values of upload_max_filesize, memory_limit and post_max_size in the php.ini configuration file. All of these three settings limit the maximum size of data that can be submitted and handled by PHP. One user also said that post_max_size and memory_limit need to be larger than upload_max_filesize. There exist several workarounds if your upload is too big or your hosting provider is unwilling to change the settings

 

해당 문서를 확인해보니 php.ini의 upload_max_filesize, memory_limit and post_max_size 를 더 증가시켜야한다고 한다. 

일단 whereis로  php.ini가 어디있는지 찾는다.

 

#whereis php

 

찾은 php.ini파일을 일단 백업하고 아래와 같이 수정작업 ㄱㄱ

memory limit은 무제한으로 하기 위해 -1로 설정했다.

 

 ; Maximum allowed size for uploaded files.
; http://www.php.net/manual/en/ini.core.php#ini.upload-max-filesize
upload_max_filesize = 200M

 

; Maximum amount of memory a script may consume (128MB)
; http://www.php.net/manual/en/ini.core.php#ini.memory-limit
memory_limit = -1

 

; Maximum size of POST data that PHP will accept.
; http://www.php.net/manual/en/ini.core.php#ini.post-max-size
post_max_size = 300M


 

 

 

그리고 http 서비스를 재시작해서 변경사항을 반영하였다.

 

service httpd restart

 

이제 정상적으로 큰 사이즈 DB도 가져오기 가능해졌다.

 

 

대신증권 API - cybos marketeye 사용하기 (C#)

MarketEye class

 

 MarketEye

 

설명

주식,지수,선물/옵션 등의 여러종목의 필요 항목들을 한번에 수신합니다.

통신종류

Request/Reply

연속여부

X

관련 SB/PB

StockCur, FutureCurOnly, OptionCurOnly

관련CYBOS

[7059] MarketEye

모듈 위치

cpsysdib.dll

Method

object.SetInputValue(type,value)

type 해당하는 입력 데이터를 value 값으로 지정합니

  • type: 입력 데이터

0 - (long or long array) 필드 또는 필드 배열. 최대 64개의 필드까지 요청가

필드

0:종목코드(string)

1:시간( ulong) - hhmm

2:대비부호(char)

코드

내용

'1'

상한

'2'

상승

'3'

보합

'4'

'5'

3:전일대비(long or float) - 주의) 반드시 대비부호(2) 같이 요청을 하여야

4:현재가(long or float)

5:시가(long or float)

6:고가(long or float)

7:저가(long or float)

8:매도호가(long or float)

9:매수호가(long or float)

10:거래량( ulong)

11:거래대금(ulonglong) - 단위:

12:장구분(char or empty)

코드

내용

'0'

장전

'1'

동시호가

'2'

장중

13:총매도호가잔량(ulong)

14:총매수호가잔량(ulong)

15:최우선매도호가잔량(ulong)

16:최우선매수호가잔량(ulong)

17:종목명(string)

20:총상장주식수(ulonglong) - 단위:

21:외국인보유비율(float)

22:전일거래량(ulong)

23:전일종가(long or float)

24:체결강도(float)

25:체결구분(char or empty)

코드

내용

'1'

매수체결

'2'

매도체

27:미결제약정(long)

28:예상체결가(long)

29:예상체결가대비(long) - 주의) 반드시 예샹체결가대비부호(30) 같이 요청을 하여야

30:예상체결가대비부호(char or empty)

코드

내용

'1'

상한

'2'

상승

'3'

보합

'4'

'5'

31:예상체결수량(ulong)

32:19일종가합(long or float)

33:상한가(long or float)

34:하한가(long or float)

35:매매수량단위(ushort)

36:시간외단일대비부호(char or empty)

코드

내용

'+'

양수

'-'

음수

37:시간외단일전일대비(long) - 주의) 반드시 시간외단일대비부호(36) 같이 요청을 하여야

38:시간외단일현재가(long)

39:시간외단일시가(long)

40:시간외단일고가(long)

41:시간외단일저가(long)

42:시간외단일매도호가(long)

43:시간외단일매수호가(long)

44:시간외단일거래량(ulong)

45:시간외단일거래대금(ulonglong) - 단위:

46:시간외단일총매도호가잔량(ulong)

47:시간외단일총매수호가잔량(ulong)

48:시간외단일최우선매도호가잔량(ulong)

49:시간외단일최우선매수호가잔량(ulong)

50:시간외단일체결강도(float)

51:시간외단일체결구분(char or empty)

코드

내용

'1'

매수체결

'2'

매도체

53:시간외단일예상/실체결구분(char)

코드

내용

'1'

예상체결

'2'

54:시간외단일예상체결가(long)

55:시간외단일예상체결전일대비(long) - 주의) 반드시 시간외예상체결대비부호(56) 같이 요청을 하여야

56:시간외단일예상체결대비부호(char or empty)

코드

내용

'1'

상한

'2'

상승

'3'

보합

'4'

하락

'5'

하한

57:시간외단일예상체결수량(ulong)

59:시간외단일기준가(long)

60:시간외단일상한가(long)

61:시간외단일하한가(long)

62:외국인순매매(long)

63:52주최고가(long or float)

64:52주최저가(long or float)

65:연중주최저가(long or float)

66:연중최저가(long or float)

67:PER(float)

68:시간외매수잔량(ulong)

69:시간외매도잔량(ulong)

70:EPS(ulong)

71:자본금(ulonglong)- 단위:백만

72:액면가(ushort)

73:배당률(float)

74:배당수익률(float)

75:부채비율(float)

76:유보율(float)

77:자기자본이익률(float)

78:매출액증가율(float)

79:경상이익증가율(float)

80:순이익증가율(float)

81:투자심리(float)

82: VR(float)

83:5 회전율(float)

84:4 종가합(ulong)

85:9 종가합(ulong)

86:매출액(ulonglong) - 단위: 백만

87:경상이익(ulonglong) - 단위:

88:당기순이익(ulonglog) - 단위:

89:BPS(ulong) - 주당순자

90:영업이익증가율(float)

91:영업이익(ulonglong) - 단위:

92:매출액영업이익률(float)

93:매출액경상이익률(float)

94:이자보상비율(float)

95:결산년월(ulong) - yyyymm

96:분기BPS(ulong) - 분기주당순자

97:분기매출액증가율(float)

98:분기영업이액증가율(float)

99:분기경상이익증가율(float)

100:분기순이익증가율(float)

101:분기매출액(ulonglong) - 단위:

102:분기영업이익(ulonglong) - 단위:

103:분기경상이익(ulonglong) - 단위:

104:분기당기순이익(ulonglong) - 단위:

105:분개매출액영업이익률(float)

106:분기매출액경상이익률(float)

107:분기ROE(float) - 자기자본순이익

108:분기이자보상비율(float)

109:분기유보율(float)

110:분기부채비율(float)

111:최근분기년월(ulong) - yyyymm

112:BASIS(float)

113:현지날짜(ulong) - yyyymmdd

114:국가명(string) - 해외지수 국가

 

1 - (string or string array) 종목코드 또는 종목코드 배열. 최대 200종목까지 가능.
주의) 해외지수와 환율은 심볼코드를 입력하여야 ) JP#NI225:니케이지

 

2 - (char) 체결비교방식

코드

내용

'1'

체결가비교방식(default)

'2'

호가비교방

 

  • value: 새로 지정할

value = object.GetHeaderValue(type)

type 해당하는 헤더 데이터를 반환합니

  • type: 데이터

0 - (long) 필드

1 - (string array) 필드명의 배열 - 필드는 요청한 필드 값의 오름차순으로 정렬되어

2 - (long) 종목

  • 반환값: 데이터 종류에 해당하는

value = object.GetDataValue (Type,index)

type 해당하는 데이터를 반환합니

  • type: 요청한 필드의 index - 필드는 요청한 필드 값으로 오름차순으로 정렬되어

  • index: 요청한 종목의 index

object.Subscribe()

사용하지

object.Unsubscribe()

사용하지

object.Request()

해당하는 데이터를 요청한

object.BlockRequest()

데이터 요청.Blocking Mode

Event

Object.Received

해당하는 데이터를 수신했을 발생하는 이벤

 

 

대신증권의 cybos API를 사용해서 주식에 관련된 다양한 정보들을 수집할 수 있다.

일단 주식에서 수급 및 재무제표의 여러  항목들을 한번에 수신할 수 있는 MarketEye 클래스에 대해 알아보자.

 

사용 언어: C#

개발 툴: visual studio

 

 

static CPSYSDIBLib.MarketEye market = new CPSYSDIBLib.MarketEye();
 

 

 

new를 이용해 MarketEye의 인스턴스를 생성한다.

이제 MarketEye의 함수들을 사용할 수 있다.

물론 해당 라이브러리(CPSYSDIBLib)는 참조추가로 프로젝트에 추가가 되어있어야한다.

 

위 레퍼런스에 적혀있듯이 SetInputValue(type,value) 함수는 두 개의 input을 받는다.

Type은 원하는 정보 type을 지정하는 데 사용되며 long 또는 long array를 입력으로 넣을 수 있다.

각각의 type값은 위 클래스 함수 설명을 참조하기 바란다.

두번째 input은 종목코드 또는 종목코드 배열로 string 이나  string array를 사용한다. 

 

데이터 요청은 BlockRequest함수로 하고 반환받은 데이터는 GetDataValue 함수를 사용해서 사용할 수 있다.

첫번째 input값은 요청한 필드의 인덱스, 두번째 input값은 요청한 회사의 인덱스 값이다.

 

 

케이스 1) 액토즈소프트 회사의 EPS를 알아보자

 

     try
            {
                market.SetInputValue(0, 70);
                market.SetInputValue(1, "A003540");
                market.BlockRequest();
            }
            catch (Exception e)
            {
                return marketList;
            }
          

 

long EPS = market.GetDataValue(0, 0);

 

 

하나의 회사의 하나의 필드 정보만 필요하기에 배열없이 그대로 입력한다.

이럴 경우 GetDataValue의 인풋값은 0,0이 된다.

 

케이스 2) 여러 게임 회사들의 다양한 값들을 배열로 받아온다.

 

요청하는 타입을 배열로 저장하고 회사 종목코드들을 배열로 저장하여 setInputValue의 input값으로 전달한다.

GetHeaderValue 함수로 반환된 타입과 회사의 개수를 알 수 있다. 함수 대신 그냥 요청했던 배열 사이즈로 대신해도 된다.  

GetDataValue (Type,index)는 요청했던 데이터를 돌려주는 함수로

Type배열과 회사코드 배열의 인덱스 값을 인자로 사용하여 해당 회사코드의 타입 값을 리턴한다.  

 

회사 코드별로 파일을 따로 만들어 요일별로 요청했던 데이터를 해당 파일에 추가하려고 한다.

아래 코드를 보면 회사코드로 파일 이름을 만들고 요청했던 필드값들을 , 를 구분자로 하여 하나의 라인으로 만들어 파일에 추가하는 것을 확인할 수 있다.

 

            int[] type_array = { 0, 1, 2, 3, 4, 10, 11, 12, 17, 20, 21, 22, 23, 24, 25, 62, 67, 68, 69 };
            string[] company_array = { "A052790", "A078340", "A112040", "A181710" };
            try
            {
           
                    market.SetInputValue(0, type_array);
                market.SetInputValue(1, company_array);
                market.BlockRequest();

            }
            catch (Exception e)
            {
                string line = string.Format("{0},", e);
                MessageBox.Show(line);
              

            }


            int field_total = market.GetHeaderValue(0);
          int company_total = market.GetHeaderValue(2);


 

             for (int company_num = 0; company_num < company_total; company_num++)
            {
                string company_name = company_array[company_num];
                string filename = string.Format("marketeye_{0}.csv", company_name);
                string total_line = "";
                for (int field_num = 0; field_num < field_total; field_num++)
                {
                    string line = string.Format("{0},", market.GetDataValue(field_num, company_num));
                    total_line += line;

                }
                System.IO.File.AppendAllText(filename, total_line, Encoding.UTF8);
                System.IO.File.AppendAllText(filename, Environment.NewLine);
            
            }

robots.txt 사용하기

최근에 개인 홈페이지를 만들고 있는데 외부에 노출되기 싫어서 robots.txt 작성법을 알아보았다.

 

robots.txt는 검색 엔진이나 웹 크롤러등의 웹 로봇이 사이트를 방문했을때

사이트의 수집 정책을 알려주기 위해 사용한다. wget에게도 사용 가능하다.

다만 정책을 알려주는 것 뿐이라  웹 로봇 작성자가 이걸 무시하고 수집해갈수도 있다.

이런 나쁜 로봇을 검출하기 위해서는 웹 로그 확인이나 트래픽 확인 등의

추가적인 작업이 필요하다.

 

 

 

사용법은 간단하다 웹 서버의 최상단 디렉토리에 robots.txt를 작성해서 넣어두면 된다.

http://www.sample.com/robots.txt

 

참고로 robots.txt는 누구나 볼 수 있다는 점을 기억하자.

간단한 작성법과 사용법은 아래와 같다.

좀더 자세한 설명을 원하는 사람은 공식 사이트에 가보자. (http://www.robotstxt.org)

 

작성법

 

User-agent: bot 이름을 따로 명시하거나 *로 전체를 나타낼 수 있다

Allow: 접근 허용하는 디렉토리 경로를 명시
Disallow: 접근을 허용하지 않는 디렉토리 경로를 명시

 

 

모두 접근 금지

 

User-agent: *
Disallow: /

 

모두 접근 허용

User-agent: *
Disallow:

 

또는 빈 robots.txt나 robots.txt를 생성하지 말 것

즉 robots.txt가 없으면 검색 대상이 되어 노출되게 된다.

 

 

간혹 상업적인 사이트에서 robots.txt가 없거나 모두 접근 허용을 하는 케이스가 있는데

회원정보나 로그인 기능이 있는 웹 사이트에서는 아래와 같이 회원정보가 있는 디렉토리는 꼭 막아두도록 하자.

 

특정 디렉토리만 접근 금지

 

User-agent: *
Disallow: /user/

 

 

 

특정 봇만 접근을 허락하기  

User-agent: Googlebot Allow: User-agent: * Disallow: /

 

 

만약 트래픽을 유발시키거나 수상한 봇이 발견되면 그 봇만 수집하지 않도록 명시는 할 수 있다.

 

User-agent: badBot
Disallow: /