2016-06-05 25 views
1

Я пытаюсь получить список временных меток в MySQL с помощью Python. Как только у меня появится список, я проверю время и проверю, какие из них длиннее 15 минут назад. Onces у меня есть, мне бы очень понравилось окончательное общее число. Это кажется более сложным, чем я думал.Python foreach from MySQLdb

Итак, я использую это, чтобы принести список из MySQL:

db = MySQLdb.connect(host=server, user=mysql_user, passwd=mysql_pwd, db=mysql_db, connect_timeout=10) 
cur = db.cursor() 
cur.execute("SELECT heartbeat_time FROM machines") 
row = cur.fetchone() 
print row 
while row is not None: 
    print ", ".join([str(c) for c in row]) 
    row = cur.fetchone() 
cur.close() 
db.close() 

>> 2016-06-04 23:41:17 
>> 2016-06-05 03:36:02 
>> 2016-06-04 19:08:56 

И это фрагмент кода я использую, чтобы проверить, если они больше, чем 15 минут назад:

fmt = '%Y-%m-%d %H:%M:%S' 
d2 = datetime.strptime('2016-06-05 07:51:48', fmt) 
d1 = datetime.strptime('2016-06-04 23:41:17', fmt) 

d1_ts = time.mktime(d1.timetuple()) 
d2_ts = time.mktime(d2.timetuple()) 

result = int(d2_ts-d1_ts)/60 

if str(result) >= 15: 
     print "more than 15m ago" 

I Не понимаю, как я могу их комбинировать. Кроме того, теперь, когда я написал это в письменном виде, должен быть более простой/лучший способ их фильтрации?

Спасибо за предложения!

+0

Я бы либо сделал это полностью на стороне MySQL, так как @sagdusmir уже сказал или использует модуль pandas, который позволяет вам легко читать данные ([read_sql()] (http://stackoverflow.com/questions/24408557/pandas -read-sql-with-parameters)), обрабатывать данные и сохранять их обратно ([to_sql()] (http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_sql.html)) – MaxU

+0

Сделайте это на сервере, верните только значение счета. Функция MySql имеет функцию NOW(). – Merlin

ответ

1

Предполагаю, что поле heartbeat_time - поле даты.

import datetime 
import MySQLdb 
import MySQLdb.cursors 

db = MySQLdb.connect(host=server, user=mysql_user, passwd=mysql_pwd, db=mysql_db, connect_timeout=10, 
        cursorclass=MySQLdb.cursors.DictCursor) 
cur = db.cursor() 

ago = datetime.datetime.utcnow() - datetime.timedelta(minutes=15) 
try: 
    cur.execute("SELECT heartbeat_time FROM machines") 
    for row in cur: 
     if row['heartbeat_time'] <= ago: 
      print row['heartbeat_time'], 'more than 15 minutes ago' 
finally: 
    cur.close() 
    db.close() 

Если размер данных не то, что огромный, загружая все из них в память хорошая практика, которая выпустит буфер памяти на сервере MySQL. И для DictCursor, нет такой разницы между ними,

rows = cur.fetchall() 
for r in rows: 

и

for r in cur: 

Они оба данных нагрузки на клиента. MySQLdb.SSCursor и SSDictCursor будут пытаться передавать данные по мере необходимости, в то время как сервер MySQL должен поддерживать его.

2

Вы можете включить проверку 15min непосредственно в ваш SQL-запрос. Таким образом, нет необходимости возиться со временными метками и IMO, гораздо легче читать код.

Если вам нужна дата из других столбцов из таблицы:

select * from machines where now() > heartbeat_time + INTERVAL 15 MINUTE;

Если общее количество единственное, что вы заинтересованы в:

SELECT count(*) FROM machines WHERE NOW() > heartbeat_time + INTERVAL 15 MINUTE;

Таким образом, вы может сделать cur.fetchone() и получить либо None, либо кортеж, где первое значение - количество строк с меткой времени старше 15 минут.

Для перебора набора результатов она должна быть достаточной, чтобы написать

 
cur.execute('SELECT * FROM machines') 
for row in cur: 
    print row 

, так как базовый курсор уже ведет себя как итератор с помощью .fetchone().

(все если у вас есть временные метки в вашей БД, как вы заявили в вопросе)

@ user5740843: if str(result) >= 15: не будет работать, как задумано. Это всегда будет True из-за str().