INVESTAR / StockAnalysisInPython

457 stars 412 forks source link

HeidiSQL 업데이트 관련 질문드립니다. #137

Open MiREUKim opened 2 years ago

MiREUKim commented 2 years ago

안녕하세요.

책의 5.3.6절까지 진행한 코드를 실행했을 때 HeidiSQL에 company_info에 '종목코드-종목-업데이트날짜'가 기록되는데요.

아래의 코드를 실행하면 정상작동 하는데, 정작 HeidiSQL에서 SELECT * FROM company_info를 입력하면 table이 3x0으로 나오지 않습니다.

혹시나 해서 아래의 코드 상에서 read_sql("SELECT * FROM company_info", self.conn)로 읽어온 데이터프레임(df)를 print(df)로 읽어보았는데, 정상적으로 '종목코드-종목-최신업데이트날짜'가 출력됩니다.

혹시 무엇이 잘못되었을까요?

아래 전체 코드입니다.

======================================================

import pymysql import pandas as pd from datetime import datetime

class DBUpdater: """ init 생성자: MariaDB 연결 및 종목코드 딕셔너리 작성 del 소멸자: 연결 해제 read_krx_code KRX로부터 상장법인목록 파일을 읽어와서 데이터프레임으로 변환 update_comp_info 종목코드를 company_info 테이블에 업데이트한 후 딕셔너리에 저장 read_naver 네이버 금융에서 주식 시세를 읽어서 데이터프레임으로 반환 replace_into_db 네이버 금융에서 읽어온 주식 시세를 DB에 REPLACE update_daily_price KRX 상장법인의 주식 시세를 네이버로부터 읽어서 DB에 업데이트 execute_daily 실행 즉시 및 매일 오후 다섯시에 daily_price 테이블 업데이트 """ def init(self): """ 생성자: MariaDB 연결 및 종목코드 딕셔너리 작성 """ self.conn = pymysql.connect(host='localhost', user='root', password='1230', db='INVESTAR', charset='utf8')

    with self.conn.cursor() as curs:
        sql = """
        CREATE TABLE IF NOT EXISTS company_info (
        code VARCHAR(20),
        company VARCHAR(40),
        last_update DATE,
        PRIMARY KEY (code))
        """
        curs.execute(sql)
        sql = """
        CREATE TABLE IF NOT EXISTS daily_price (
        code VARCHAR(20),
        date DATE,
        open BIGINT(20),
        high BIGINT(20),
        low BIGINT(20),
        close BIGINT(20),
        diff BIGINT(20),
        volume BIGINT(20),
        PRIMARY KEY (code, date))
        """
        curs.execute(sql)
    self.conn.commit()
    self.codes = dict()
    self.update_comp_info()

def __del__(self):
    """ 소멸자: 연결 해제 """
    self.conn.close()

def read_krx_code(self):
    """ KRX로부터 상장법인목록 파일을 읽어와서 데이터프레임으로 변환 """
    url = 'http://kind.krx.co.kr/corpgeneral/corpList.do?method='\
        'download&searchType=13'
    krx = pd.read_html(url, header=0)[0]
    krx = krx[['종목코드', '회사명']]
    krx = krx.rename(columns={'종목코드': 'code', '회사명': 'company'})
    krx.code = krx.code.map('{:06d}'.format)
    return krx

def update_comp_info(self):
    """ 종목코드를 company_info 테이블에 업데이트한 후 딕셔너리에 저장 """
    sql = "SELECT * FROM company_info"
    df = pd.read_sql(sql, self.conn)
    print(df)
    for idx in range(len(df)):
        self.codes[df['code'].values[idx]] = df['company'].values[idx] # 종목코드와 회사명으로 codes 딕셔너리 생성

    with self.conn.cursor() as curs:
        sql = "SELECT max(last_update) FROM company_info"
        curs.execute(sql)
        rs = curs.fetchone() # DB에서 가장 최근 업데이트 날짜 가져옴
        today = datetime.today().strftime('%Y-%m-%d')
        if rs[0] == None or rs[0].strftime('%Y-%m-%d') < today: # 최신 업데이트 날짜가 없거나 오늘보다 오래된 경우에만 업데이트
            krx = self.read_krx_code() # KRX 상장기업 목록 파일 읽어서 krx 데이터프레임에 저장
            for idx in range(len(krx)):
                code = krx.code.values[idx]
                company = krx.company.values[idx]
                sql = f"REPLACE INTO company_info (code, company, last"\
                    f"_update) VALUES ('{code}', '{company}', '{today}')"
                curs.execute(sql) # '종목코드, 회사명, 오늘날짜' 행을 DB에 저장
                self.codes[code] = company # codes 딕셔너리에 '키-값'으로 종목코드와 회사명 추가
                tmnow = datetime.now().strftime('%Y-%m-%d %H:%M')
                print(f"[{tmnow}] #{idx+1:04d} REPLACE INTO company_info "\
                      f"VALUES ({code}, {company}, {today})")
            self.conn.commit()
            print('')

def read_naver(self):
    """ 네이버 금융에서 주식 시세를 읽어서 데이터프레임으로 반환 """

def replace_into_db(self, df, num, code, company):
    """ 네이버 금융에서 읽어온 주식 시세를 DB에 REPLACE """

def update_daily_price(self, pages_to_fetch):
    """ KRX 상장법인의 주식 시세를 네이버로부터 읽어서 DB에 업데이트 """

def execute_daily(self):
    """ 실행 즉시 및 매일 오후 다섯시에 daily_price 테이블 업데이트 """

if name == 'main': dbu = DBUpdater() dbu.update_comp_info()

dbu.execute_daily()

INVESTAR commented 2 years ago

read_sql("SELECT * FROM company_info", self.conn) 위 코드의 결과를 데이터프레임으로 출력했을 때 정상적으로 표시가 되는 것으로 봐서는 INVESTAR 데이터베이스의 company_info 테이블에는 정상적으로 데이터가 기록되어 있는 것 같습니다.

HeidiSQL에서 SELECT * FROM company_info 쿼리를 실행했던 대상 데이터베이스와 테이블이 DBUpdater 대상 데이터베이스/테이블과 동일한지 확인해 보시기 바랍니다.