2009-08-03 5 views
1

while 루프에서 'day'를 SQL 문으로 전달하려고합니다.이 명령문은 -ePython에서 os.system을 통해 명령 줄에서 MySQL 쿼리 실행하기

과 함께 실행될 MySQL 명령 줄로 전달됩니다.

DB 모듈이나 다른 파이썬 라이브러리를 사용하여 MySQL에 액세스 할 수 없으므로 명령 행을 통해 수행해야합니다. 또한 sql에 연결하기 전에 하루를 문자열로 변환해야 할 수도 있습니다.

#!/usr/bin/python 

import datetime 


a = datetime.date(2009, 1, 1) 
b = datetime.date(2009, 7, 1) 
one_day = datetime.timedelta(1) 

day = a 

while day <= b: 
print day 

sql="SELECT Date,SUM(CostUsd) FROM Stats d WHERE d.Date = " + day + " GROUP BY Date" 

print "SELECT Date,SUM(CostUsd) FROM Stats d WHERE d.Date = " + day + " GROUP BY Date" 

os.system('mysql -h -sN -u -p -e " + sql + " > /home/output/DateLoop-" + day + ".txt db') 
day += one_day 

입력 파일로 SQL을 가지고 것과 문자열로 일 통과하려면이 옵션을 설정할 수 있을까요? 쿼리가 복잡해 지거나 여러 쿼리가 필요할 수도 있으며 문자열로 전달하려고하면 문제가 될 수 있습니다.

내가 한 쿼리가 입력으로 일을 같은 날짜 출력 파일 이름을 지정하고 MySQL 클라이언트가

+0

MySQLdb 모듈 사용시 문제점은 무엇입니까? – alberge

답변

1

명시 적 형식을 시도 명령 줄에서 그것을 할 수있는 어떤 아이디어에 개방이고 결과 문자열을 인용 :

os.system("mysql db -h -sN -u -p -e '" + sql + "' > /home/output/DateLoop-" + day + ".txt") 
0

잘 os.system을 호출에서

sql = "....WHERE d.Date = '" + date.isoformat() + "' GROUP BY ..." 

지수가 지저분하고 (이것은 오타가 아니라면) 리디렉션 이상한 보면, 당신은 MySQL의 템플릿 네가 윌리엄 이니 저장할 수 있습니다 설정 파일에 y를 ConfigParser로 구문 분석 :

[mysql query configuration] 
dbhost = 
db = 
username = guest 
password = 

[query template] 
template = SELECT Date, SUM(CostUsd)....... 

아니면 그냥 별도의 파일로 저장 한 다음 표준 개방 (파일 이름을 읽을 수 있습니다

설정 파일이 그 모양을) .read 등. 미래에 쿼리가 더 복잡해질 것이라고 생각하면 config 파일 접근법이 관리하고 이해하기가 더 간단 할 수 있지만 큰 차이는 아닙니다.

는 매개 변수로 날짜를 얻으려면 당신은 당신을 도울 수 아래 optparse

3

코드처럼 sys.argv에, 또는 라이브러리를 사용할 수 있습니다. 특히 흥미롭지는 않으며 의도적으로 단순합니다. 이것은 많은 프로그래머가이 문제를 해결하는 방법이 아니지만 더 많은 정보가 없으면 요구 사항을 충족시키는 것으로 보입니다.

나는 또한 당신이 파이썬을 처음 사용한다고 가정했다; 내가 틀렸다면이 글을 무시해도 좋습니다.

  • 데이터베이스 자격 증명, 출력 디렉토리 및 날짜 (시작 및 종료)를 명령 줄에서 전달할 수 있습니다.
  • os.system 대신 subprocess를 사용합니다. Subprocess는 Python에서 외부 실행 파일을 호출하는 기본 메커니즘을 제공합니다. 이 코드는 가장 간단한 것을 사용합니다. call()은 os.system()과 유사하므로
  • optparse를 사용하여 명령 줄 인수를 처리합니다. 코드가 확실히 길고 장황하면, 장래에 arg 처리에 추가와 변경을 더 쉽게 할 수 있습니다. 또한 어떤 일이 일어나고 있는지 명확히 알 수 있습니다. 코드는 항상 작성된 것보다 훨씬 자주 읽혀집니다.
  • 명령 줄 설정은 스크립트가 __main__ 블록 내에서 실행될 때만 실행됩니다. 스크립트의 "논리"는 main() 메소드 내에 있기 때문에이를 가져 와서 다른 소스의 옵션 객체 (및 arg 목록)를 제공 할 수도 있습니다.

각 날짜를 별도의 파일로 출력해야 할 필요가 없으면 데이터베이스 엔진에서 SUM()을 계산하고 날짜별로 그룹화하도록 할 수 있습니다. 더 빠르고 더 간단한 코드를 생성 할 수있는 하나의 db 호출에서 모든 합계를 얻을 수 있습니다.

#!/usr/bin/python 
# -*- coding: utf-8 -*- 

import datetime 
import os 
import subprocess 
from optparse import OptionParser 

SQL = """SELECT d.Date, SUM(d.CostUsd) FROM Stats d WHERE d.Date = '%s' GROUP BY d.Date""" 


def get_stats(options, dateobj): 
    """Return statistics for the date of `dateobj`""" 
    _datestr = dateobj.strftime('%Y-%m-%d') 
    sql = SQL % _datestr 
    filepath = os.path.join(options.outdir, 'DateLoop-%s.txt' % _datestr) 
    return subprocess.call('mysql -h %s -u %s -p -sN -e "%s" db > %s' % (options.dbhost, options.dbuser, sql, filepath), shell=True) 


def main(options, args): 
    """""" 
    _date = options.startdate 
    while _date <= options.enddate: 
     rs = get_stats(options, _date) 
     _date += datetime.timedelta(days=1) 


if __name__ == '__main__': 
    parser = OptionParser(version="%prog 1.0") 
    parser.add_option('-s', '--startdate', type='string', dest='startdate', 
     help='the start date (format: yyyymmdd)') 

    parser.add_option('-e', '--enddate', type='string', dest='enddate', 
     help='the end date (format: yyyymmdd)') 

    parser.add_option('--output', type='string', dest='outdir', default='/home/output/', 
     help='target directory for output files') 

    parser.add_option('--dbhost', type='string', dest='dbhost', default='myhost', 
     help='SQL server address') 

    parser.add_option('--dbuser', type='string', dest='dbuser', default='dbuser', 
     help='SQL server user') 

    options, args = parser.parse_args() 

    ## Process the date args 
    if not options.startdate: 
     options.startdate = datetime.datetime.today() 
    else: 
     try: 
      options.startdate = datetime.datetime.strptime('%Y%m%d', options.startdate) 
     except ValueError: 
      parser.error("Invalid value for startdate (%s)" % options.startdate) 

    if not options.enddate: 
     options.enddate = options.startdate + datetime.timedelta(days=7) 
    else: 
     try: 
      options.enddate = datetime.datetime.strptime('%Y%m%d', options.enddate) 
     except ValueError: 
      parser.error("Invalid value for enddate (%s)" % options.enddate) 

    main(options, args) 
관련 문제