반응형

mysql

+그룹별로 처음 나오는 하나의 줄만 뽑아낼때


ex) CAT_ID가 같은 것들끼리 묶어서 그룹별 처음으로 나온 레코드만 그룹 대표로 하나씩 추출한다.

select * from TABLE_A group by CAT_ID ;


그룹 내에서 어떤 키로 소팅하여 최신 값을 뽑는 경우, min, max 함수등을 이용하거나 미리 order by로 정렬 후 group by로 한다.

ex)

select * from (select * from TABLE_A order by NAME desc) a group by a.CAT_ID ;

select CAT_ID, min(NAME) from TABLE_A group by CAT_ID ;



+ group by 에러

only_full_group_by 에러가 발생.

=> mysql 5.7이상 부터 group by로 select 할 때 다른 값들이 있는 컬럼들을 조회하면 에러 발생.

처음 나온 것들을 자동으로 선택하여 조회하게 하려면 서버 설정을 바꿔주어야 한다.

/etc/mysql/my.cnf

[mysqld]

sql_mode=STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION

위와 같이 설정을 추가하여 서비스 재시작

service mysql restart





반응형

python file i/o, directory, read/write

-파일 IO

파일객체=open(file, mode)

간략하게
f = open('a.txt') 이렇게도 된다.

-mode 
r ; read (default)
r+ ; read/write
w ; write
a    ; append
t    ; text mode (default)
b ; binary

contents=f.read()    ; 전체 읽기
str=f.readline()    ; 한 줄 읽기 (\n포함!), 더 읽을게 없으면 None 리턴.
strarray=f.readlines() ; 여러줄을 읽어 list로 반환. (\n포함!)

f = open('filename', 'mode')
while 1:
     line = f.readline()    # 마지막에 \n도 포함되어 줄 단위로 읽는다.
     if not line : break
     print(line)
f.write(buf)
f.close()

여러줄 읽기
lines = f.readlines()
tell(), seek() 지원



+ 파일 열기
f = open('c:\\users\\user01\\desktop\\a.txt', 'rt')
     오픈 모드 ; r=read, w=write
               t=text, b=binary
+ 읽기
lines = f.readlines()          # 여러줄 읽기. string list로 반환. (마지막에 \n도 포함됨.)                                     제거하려면, rstrip() 사용
f.close()

for line in lines:
     print(line, end="")     # 라인마지막에 \n이 포함되어 있어서 print에서 자체 \n을 제거하여 출력.


-파일 IO

파일객체=open(file, mode)
간략하게
f = open('a.txt') 이렇게도 된다.

-mode ; 
r ; read (default)
r+ ; read/write
w ; write
a    ; append
t    ; text mode (default)
b ; binary

f.read()    ; 전체 읽기
f.readline()    ; 한 줄 읽기 (\n포함), 더 읽을게 없으면 None 리턴.
f.readlines() ; 여러줄을 읽어 list로 반환. (\n포함)

f = open('filename', 'mode')
while 1:
     line = f.readline()    # 마지막에 \n도 포함되어 줄 단위로 읽는다.
     if not line : break
     print(line)
f.write(buf)
f.close()
모드는 r,w,a
여러줄 읽기
lines = f.readlines()
tell(), seek() 지원



+ 파일 열기
f = open('c:\\users\\user01\\desktop\\a.txt', 'rt')
     오픈 모드 ; r=read, w=write
               t=text, b=binary

+ 읽기
lines = f.readlines()          # 여러줄 읽기. string list로 반환. (마지막에 \n도 포함됨.) 제거하려면, rstrip() 사용
f.close()

for line in lines:
     print(line, end="")     # 라인마지막에 \n이 포함되어 있어서 print에서 자체 \n을 제거하여 출력.

+쓰기
f = open('a.txt', 'wt')
f.write('test\n')
f.write('test2\n')
f.close()

f.seek(위치)
f.tell()    ; 현재 위치

f = open('a.txt', 'wt')
f.write('test\n')
f.write('test2\n')
f.close()

f.seek(위치)
f.tell()    ; 현재 위치






+ OS, sys 모듈

import os
               print (os.getcwd())          ; 현재 디렉터리
os.listdir('c:\python27')        ; dir list
os.rename('a.txt', 'b.txt')     ; rename file
os.chdir('/users/...')          ; cd

os.path.join('/users/aa', 'a.py')          ; 경로 만들기
os.path.expanduser('~')     ; home dir
(dirname, filename) = os.path.split(pathname)          ; directory, filename 분리
(shortname, ext) = os.path.splitext(filename)               ; filename, extension 분리 ; 
abc.py -> abc, .py



++ 현재 소스 디렉터리

srcdir = os.path.dirname( os.path.abspath(__file__))

print('srcdir=', srcdir)



+ listing directory          
import glob                              ; glob module ; shell wild card support!
glob.glob('examples/*.xml')         ; 파일 목록 조회


+ file info
metadata = os.stat('feed.xml')
metadata.st_mtime
123332323.32233223
time.localtime(metadata.st_mtime)     ; time.struct_time( tm_year, tm_mon, tm_mday, tm_hour, tm_min...)
metadata.st_size     ; file size

import humansize
humansize.approximate_size( metadata.st_size)     ; '3.0 KiB'

-전체 경로 얻기
os.path.realpath('feed.xml')          ; full path

os.getcwd() ; 현재 디렉터리
os.chdir(…) ; 현재 디렉터리 이동

os.path.isdir(...)     
os.path.isfile(...)     ; 존재여부 & 파일타입
os.path.isexists(...) ; 존재 여부
os.path.getsize(...)  ; 파일 크기
os.path.split(...')     ; (dir, file) 두 부분으로 잘라준다. 두 부분을 나누는 delimeter는 제외.
os.path.join(dir,filename) ; 두 개를 합쳐준다.
os.sep    ; os seperator 문자. / or \
os.path.normpath(mixed) ; / 와 \가 섞였을때 고쳐준다.

os.getpid()     ; process id
os.getuid()     ; process's real user id
os.getlogin()     ; user id
os.mkdir('c:\\test\\test1\\test2')     ; mkdir(path [,mode])     default mode = 0777, if exist? OSError.

os.makedirs(path[, mode]) ; 중간 경로 생성. if exist, error.  에러 무시하려면?      exist_ok=True를 추가함.
os.makedirs('c:\\test\\test1\\test2', exist_ok=True)




반응형

[Python에서 API서비스 구현하기]


POST로 JSON 요청받아 작업쓰레드를 돌려서 비동기 방식으로 작업하고,

진행 상태를 체크할 수 있는 구조.

Flask 사용.



- 구동 쉘 스크립트 ; server_run.sh

#!/bin/bash
/opt/anaconda3/envs/tensorflow/bin/python server_learn.py

- 서버 ; server_learn.py


from flask import Flask, request
from flask_restful import Resource, Api
from flask.views import MethodView
import json, base64
import string
import random
import os
import threading, time

app = Flask(__name__)
api = Api(app)

# 랜덤스트링 생성하는 함수. 세션키 생성 등
def random_string(size=6, chars=string.ascii_lowercase+string.digits):
return ''.join(random.choice(chars) for _ in range(size))


# 글로벌
g_bworking=False    # 작업 여부.
g_progress = 0        # 진행 상태. 0~100
g_elapsedtime = 0    # 소요 시간. sec
g_workresult={}    # 작업 결과
g_workname=''       # 작업명

# 워커 쓰레드 ; 1~p1까지 sum구하기. 루프 돌때마다 p2 sec만큼 sleep.
def work(myid, p1, p2):
global g_bworking, g_progress, g_workresult, g_elapsedtime
starttime = time.time()

if g_bworking==True:
print('server is busy...')
return 0
g_bworking=True
g_workresult={}
g_progress=0
g_elapsedtime=0
total = 0
for i in range(1, (p1+1)):
total+=i
time.sleep(p2)
print('work : total[',myid,'] = ', total)

g_progress = 100* i / (p1)
g_elapsedtime = time.time() - starttime


endtime = time.time()
g_elapsedtime = endtime - starttime
g_workresult={'total':total, 'until':p1, 'sleep': p2}
g_progress=100
g_bworking=False
return total


class mysum(MethodView):
def get(self):
data = request.args
print(data) # dictionary
return {'name':'test'}

def options(self):
print('options.')
data = request.get_json() # application/json
print(data)
return {'Allow':'PUT,GET,POST'}, 200, \
{'Access-Control-Allow-Origin': '*', \
'Access-Control-Allow-Headers':'Content-Type,Authorization',\
'Access-Control-Allow-Methods': 'PUT,GET,POST'}

def post(self):
global g_workname
# data = request.form
# print(data) # dictionary
data = request.get_json() # application/json
print(data)

if g_bworking==True:
LearnResult = { 'result': 0 }
else:
num = int(data['num'])
slp = int(data['slp'])
g_workname = data['name']
t = threading.Thread(target=work, args=(g_workname, num, slp))
t.start()
LearnResult = {
'result': 1
}
return LearnResult


class status(MethodView):
def get(self):
data = request.args
print(data) # dictionary
if g_progress > 0 :
predtime = g_elapsedtime * 100 / g_progress
else:
predtime = 0
result = { 'work':int(g_bworking),
'workname':g_workname,
'progress':str(g_progress),
'workresult': g_workresult,
'elapsedtime':str(g_elapsedtime),
'remaintime': str(predtime - g_elapsedtime) }
return result

api.add_resource(mysum, '/mysum')
api.add_resource(status, '/status')

if __name__=='__main__':
app.run(host='0.0.0.0', port=18899, debug=True)


- 테스트

http://127.0.0.1:18899/mysum

POSTDATA ; 1~10까지 합 요청. 단계별로 1초씩 쉼.

{

    "num": "10",

    "slp": "1",

    "name": "work1"

}

response: 즉시 아래와 같이 성공 리턴됨.

{

    "result": 1

}



http://127.0.0.1:18899/status

GET

주기적으로 상태 체크 API 호출하여 결과 확인.

{

    "workresult": {

        "until": 10,

        "total": 55,

        "sleep": 1

    },

    "remaintime": "0.0",

    "workname": "work1",

    "elapsedtime": "10.011629581451416",

    "work": 0,

    "progress": "100"

}









+ Recent posts