2015-06-17 3 views
2

Я разбор несколько лет стоит ежедневных солнечных поколения CSV файлов, которые выглядят следующим образом (в формате ГГ-ММ-DD.CSV имени файла)Python Datetime в MySQL

sep=; 
Version CSV|Tool SunnyBeam11|Linebreaks CR/LF|Delimiter semicolon|Decimalpoint point|Precision 3|Language en-UK|TZO=0|DST|11/03/2012 

    ;SN: xyz 
    ;SB blah 
    ;xyz 
    Time;Power 
    HH:mm;kW 
    00:10;0.000 
    00:20;0.000 
    00:30;0.000 
    00:40;0.000 
    00:50;0.000 
    01:00;0.000 
    01:10;0.000 
    01:20;0.000 
    01:30;0.000 
    01:40;0.000 
    01:50;0.000 
    02:00;0.000 
    02:10;0.000 
    02:20;0.000 
    02:30;0.000 
    02:40;0.000 
    02:50;0.000 
    03:00;0.000 
    03:10;0.000 
    03:20;0.000 
    03:30;0.000 
    03:40;0.000 
    03:50;0.000 
    04:00;0.000 
    04:10;0.000 
    04:20;0.000 
    04:30;0.000 
    04:40;0.000 
    04:50;0.000 
    05:00;0.000 
    05:10;0.000 
    05:20;0.000 
    05:30;0.000 
    05:40;0.000 
    05:50;0.000 
    06:00;0.000 
    06:10;0.000 
    06:20;0.000 
    06:30;0.000 
    06:40;0.000 
    06:50;0.000 
    07:00;0.000 
    07:10;0.012 
    07:20;0.048 
    07:30;0.072 
    07:40;0.078 
    07:50;0.114 
    08:00;0.150 
    08:10;0.156 
    08:20;0.168 
    08:30;0.204 
    08:40;0.180 
    08:50;0.198 
    09:00;0.210 
    09:10;0.222 
    09:20;0.294 
    09:30;0.330 
    09:40;0.342 
    09:50;0.402 
    10:00;0.492 
    10:10;0.396 
    10:20;0.474 
    10:30;1.224 
    10:40;1.374 
    10:50;1.416 
    11:00;1.470 
    11:10;1.500 
    11:20;1.530 
    11:30;1.530 
    11:40;1.542 
    11:50;1.536 
    12:00;1.554 
    12:10;1.584 
    12:20;1.584 
    12:30;1.572 
    12:40;1.560 
    12:50;1.548 
    13:00;1.518 
    13:10;1.494 
    13:20;1.470 
    13:30;1.440 
    13:40;1.404 
    13:50;1.356 
    14:00;1.332 
    14:10;1.284 
    14:20;1.236 
    14:30;1.194 
    14:40;1.110 
    14:50;1.050 
    15:00;0.972 
    15:10;0.888 
    15:20;0.816 
    15:30;0.744 
    15:40;0.648 
    15:50;0.594 
    16:00;0.528 
    16:10;0.438 
    16:20;0.342 
    16:30;0.264 
    16:40;0.228 
    16:50;0.180 
    17:00;0.120 
    17:10;0.084 
    17:20;0.048 
    17:30;0.024 
    17:40;0.006 
    17:50;0.000 
    18:00;0.000 
    18:10;0.000 
    18:20;0.000 
    18:30;0.000 
    18:40;0.000 
    18:50;0.000 
    19:00;0.000 
    19:10;0.000 
    19:20;0.000 
    19:30;0.000 
    19:40;0.000 
    19:50;0.000 
    20:00;0.000 
    20:10;0.000 
    20:20;0.000 
    20:30;0.000 
    20:40;0.000 
    20:50;0.000 
    21:00;0.000 
    21:10;0.000 
    21:20;0.000 
    21:30;0.000 
    21:40;0.000 
    21:50;0.000 
    22:00;0.000 
    22:10;0.000 
    22:20;0.000 
    22:30;0.000 
    22:40;0.000 
    22:50;0.000 
    23:00;0.000 
    23:10;0.000 
    23:20;0.000 
    23:30;0.000 
    23:40;0.000 
    23:50;0.000 
    00:00;0.000 


    E-Today kWh;8.313 
    E-Total kWh;67.471 

Моего Python способен разобрать дату в последнем поле строки 2, а затем итеративно объединить его со временем в каждой строке. Использование комбинации даты и времени в качестве метки времени (тип несовместимости, вероятно, проблема?) Я пытаюсь вставить ее в базу данных mySQL в столбец типа timestamp (и включить в столбец типа DECIMAL (4,3))

Я играл с различными комбинациями типов, но явно не в правильном направлении. Я был бы очень благодарен эксперту Python за разъяснение того, как успешно получить синтезированную дату в форме, совместимой с временной меткой MySQL.

Питон является:

#!/usr/bin/python 

from os import listdir 
from datetime import datetime 
import MySQLdb 
#from sys import argv 


def is_dated_csv(filename): 
    """ 
    Return True if filename matches format YY-MM-DD.csv, otherwise False. 
    """ 
    date_format = '%y-%m-%d.csv' 

    try: 
     date = datetime.strptime(filename, date_format) 
     return True 
    except ValueError: 
     # filename did not match pattern 
     print filename + ' did NOT match' 
     pass 
#'return' terminates a function 
    return False 


def parse_for_date(filename): 
    """ 
    Read file for the date - from line 2 field 10 
    """ 
    currentFile = open(filename,'r') 
    l1 = currentFile.readline() #ignore first line read 
    date_line = currentFile.readline() #read second line 
    dateLineArray = date_line.split("|") 
    day_in_question = dateLineArray[-1]#save the last element (date) 
    currentFile.close() 
    return day_in_question 


def normalise_date_to_UTF(day_in_question): 
    """ 
    Rather wierdly, some days use YYYY.MM.DD format & others use DD/MM/YYYY 
    This function normalises either to UTC with a blank time (midnight) 
    """ 
    if '.' in day_in_question: #it's YYYY.MM.DD 
    dateArray = day_in_question.split(".") 
    dt = (dateArray[0] +dateArray[1] + dateArray[2].rstrip() + '000000') 
    elif '/' in day_in_question: #it's DD/MM/YYYY 
    dateArray = day_in_question.split("/") 
    dt = (dateArray[2].rstrip() + dateArray[1] + dateArray[0] + '000000') 
    theDate = datetime.strptime(dt,'%Y%m%d%H%M%S') 
    return theDate #A datetime object 


def parse_power_values(filename, theDate): 
    currentFile = open(filename,'r') 
    for i, line in enumerate(currentFile): 
    if i <= 7: 
     doingSomething = True 
     #print 'header' + str(i) + '/ ' + line.rstrip() 
    elif ((i > 7) and (i <= 151)): 
     lineParts = line.split(';') 
     theTime = lineParts[0].split(':') 
     theHour = theTime[0] 
     theMin = theTime[1] 
     timestamp = theDate.replace(hour=int(theHour),minute=int(theMin)) 
     power = lineParts[1].rstrip() 
     if (float(power) > 0): 
     #print str(i) + '/ ' + str(timestamp) + ' power = ' + power + 'kWh' 
     append_to_database(timestamp,power) 
     #else: 
     # print str(i) + '/ ' 
    elif i > 151: 
     print str(timestamp) + ' DONE!' 
     print '----------------------' 
     break 
    currentFile.close() 

def append_to_database(timestampval,powerval): 
    a = datetime.strptime(timestampval,"%b %d %Y %H:%M") 
    host="localhost", # your host, usually localhost 
    user="root", # your username 
    passwd="******" 
    database_name = 'SunnyData' 
    table_name = 'DTP' 
    timestamp_column = 'DT' 
    power_column = 'PWR' 
    sql = ("""INSERT INTO %s(%s,%s) VALUES(%s,'%s')""", ('table_name', 'timestamp_column', 'power_column', a.strftime('%Y-%m-%d %H:%M:%S'), powerval)) 
    print sql 
    #db = MySQLdb.connect(host,user,passwd,database_name) 
    cur = SD.cursor() 
    try: 
    cur.execute(sql) 
    print 'SQL: ' + sql 
    SD.commit() 
    except: 
    print 'DB append failed!' 
    SD.rollback() 

# Main start of program 
path = '.' 
for filename in listdir(path): 
    if is_dated_csv(filename): 
     SD = MySQLdb.connect(host="localhost", user="root",passwd="**********", db = 'SunnyData') 
     print filename + ' matched' 
     # Do something with the desired .csv file 
     day_in_question = parse_for_date(filename) 
     print 'the date is ' + day_in_question 
     theDate = normalise_date_to_UTF(day_in_question) 
     parse_power_values(filename, theDate) 
     SD.close() 

    pass 

и DB создать SQL выглядит следующим образом

CREATE TABLE `DTP` (
    `idDTP` int(11) NOT NULL, 
    `DT` timestamp NULL DEFAULT NULL, 
    `PWR` decimal(4,3) DEFAULT NULL, 
    PRIMARY KEY (`idDTP`) 
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

Большое спасибо,

Грег (Python новичок)

+1

Thats много кода, который вы хотите, чтобы люди просматривали. Пожалуйста, подумайте о сокращении его до MCVE. См. Этот http://stackoverflow.com/help/mcve. – Dan

+0

Самый длинный раздел - это всего лишь файл данных, показывающий, что было проанализировано, и я подозреваю, что могу показать только раздел Python, где я подозреваю, что проблема (def append_to_database()), но TBH его, возможно, нет, поэтому я оставил все , Наконец, я хотел убедиться, что проблема не в Schema, поэтому я включил короткий SQL-создание. Надеюсь, все в порядке. Я буду помнить об этом в следующий раз: o) – Greg

+0

Когда вы печатаете, отображает ли он соответствующий формат, который вы ожидаете от MySQL для TIMESTAMP? Вы пытались использовать DATETIME вместо этого? Есть некоторые тонкости, которые могут быть проблемой. – Dan

ответ

2

Я взял код , и кажется, что основные проблемы находятся в функции append_to_database.

Похоже, возвращаемое значение normalise_date_to_UTF возвращает Задан объект, который передается в append_to_database (как timestampval аргумента), и что в настоящее время проходят через strptime, что нет необходимости, так как это не строка, а уже DateTime ,

Оператор SQL также нуждался в некоторой корректировке для того, как вы заменяете переменные в строках. В python оператор %, следуя строке, позволяет вставлять значения в эту строку с помощью кодов формата. Кроме того, table_name, timestamp_column и power_column имели одинарные кавычки вокруг них, что означало, что буквальная строка будет вставлена, а не значение переменной.

В основном ваша append_to_database функция должна выглядеть следующим образом:

def append_to_database(timestampval,powerval): 
    host="localhost", # your host, usually localhost 
    user="root", # your username 
    passwd="******" 
    database_name = 'SunnyData' 
    table_name = 'DTP' 
    timestamp_column = 'DT' 
    power_column = 'PWR' 
    sql = ("INSERT INTO %s (%s,%s) VALUES('%s','%s')" % (table_name, timestamp_column, power_column, timestampval.strftime('%Y-%m-%d %H:%M:%S'), powerval)) 
    print sql 
    #db = MySQLdb.connect(host,user,passwd,database_name) 
    cur = SD.cursor() 
    try: 
    cur.execute(sql) 
    print 'SQL: ' + sql 
    SD.commit() 
    except: 
    print 'DB append failed!' 
    SD.rollback() 

Что касается БД MySQL, SQL-вставки не определяя значение для idDTP столбца, а столбец автоматически не инкрементацию, поэтому после python вставляет первое значение, все последующие вставки будут терпеть неудачу, потому что значение по умолчанию равно 0 для каждой вставки. Это может быть разрешено одним из двух способов, изменяя код python, чтобы указать значение для idDTP или установку idDTP для автоматического увеличения.

Если вы хотите изменить таблицу, чтобы иметь авто Инкрементирование идентификаторов, то SQL синтаксис (запустить на сервере MySQL) является:

ALTER TABLE DTP MODIFY COLUMN idDTP INT auto_increment 

или вы можете воссоздать таблицу, как это:

CREATE TABLE `DTP` (
    `idDTP` int(11) NOT NULL AUTO_INCREMENT, 
    `DT` timestamp NULL DEFAULT NULL, 
    `PWR` decimal(4,3) DEFAULT NULL, 
    PRIMARY KEY (`idDTP`) 
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

Я побежал код, делая изменения выше, и с первой частью предоставленных данных, при запросе MySQL для таблицы DTP, это выглядит следующим образом:

select * from DTP; 
+-------+---------------------+-------+ 
| idDTP | DT     | PWR | 
+-------+---------------------+-------+ 
|  1 | 2012-03-11 07:10:00 | 0.012 | 
|  2 | 2012-03-11 07:20:00 | 0.048 | 
|  3 | 2012-03-11 07:30:00 | 0.072 | 
|  4 | 2012-03-11 07:40:00 | 0.078 | 
|  5 | 2012-03-11 07:50:00 | 0.114 | 
|  6 | 2012-03-11 08:00:00 | 0.150 | 
|  7 | 2012-03-11 08:10:00 | 0.156 | 
|  8 | 2012-03-11 08:20:00 | 0.168 | 
|  9 | 2012-03-11 08:30:00 | 0.204 | 
| 10 | 2012-03-11 08:40:00 | 0.180 | 
+-------+---------------------+-------+ 

Надеюсь, что поможет вам в этом проекте!

+0

Спасибо. Ошибка школьника при автоматическом приращении: o) – Greg

Смежные вопросы