2014-02-05 4 views
0

Правильно ли это получить список из SQL-запроса в Python 2.7? Использование цикла просто кажется каким-то ложным. Есть лучший способ лучше?Правильный способ заполнения списка из SQL-запроса с помощью pyodbc

import numpy as np 
import pyodbc as SQL 
from datetime import datetime 

con = SQL.connect('Driver={SQL Server};Server=MyServer; Database=MyDB; UID=MyUser; PWD=MyPassword') 
cursor = con.cursor() 

#Function to convert the unicode dates returned by SQL Server into Python datetime objects 
ConvertToDate = lambda s:datetime.strptime(s,"%Y-%m-%d") 

#Parameters 
Code = 'GBPZAR' 

date_query = ''' 
      SELECT DISTINCT TradeDate 
      FROM MTM 
      WHERE Code = ? 
       and TradeDate > '2009-04-08' 
      ORDER BY TradeDate 
      ''' 

#Get a list of dates from SQL 
cursor.execute(date_query, [Code]) 
rows = cursor.fetchall() 
Dates = [None]*len(rows) #Initialize array 
r = 0 
for row in rows: 
    Dates[r] = ConvertToDate(row[0]) 
    r += 1 

Edit:

А когда я хочу поставить запрос в структурированный массив? На данный момент я сделать что-то вроде этого:

#Initialize the structured array 
AllData = np.zeros(num_rows, dtype=[('TradeDate', datetime), 
            ('Expiry', datetime), 
            ('Moneyness', float), 
            ('Volatility', float)]) 

#Iterate through the record set using the cursor and populate the structure array 
r = 0 
for row in cursor.execute(single_date_and_expiry_query, [TradeDate, Code, Expiry]): 
    AllData[r] = (ConvertToDate(row[0]), ConvertToDate(row[1])) + row[2:] #Convert th0e date columns and concatenate the numeric columns 
    r += 1 

ответ

1

Там нет необходимости предварительно создать список, вы могли бы использовать вместо list.append(). Это также позволяет избежать необходимости держать счетчик индексов в Dates.

Я хотел бы использовать список понимание здесь, зацикливание непосредственно над курсором для выборки строк:

cursor.execute(date_query, [Code]) 
Dates = [datetime.strptime(r[0], "%Y-%m-%d") for r in cursor] 

Вы можете добавить .date() к datetime.strptime() результате получить datetime.date объекты вместо этого.

Итерация над курсором предпочтительнее, поскольку она позволяет избежать загрузки всех строк в виде списка в память, только для замены этого списка другим, обработанным списком дат. Смотрите cursor.fetchall() documentation:

Поскольку это считывает все строки в память, его нельзя использовать, если имеется много строк. Рассмотрим вместо этого итерацию по строкам.

Чтобы создать numpy.array, не заново заполняйте. Вместо того, чтобы использовать numpy.asarray(), чтобы включить элементы управления курсором в массив, с помощью генератора:

dtype=[('TradeDate', datetime), ('Expiry', datetime), 
     ('Moneyness', float), ('Volatility', float)] 
dt = lambda v: datetime.strptime(v, "%Y-%m-%d") 
filtered_rows = ((dt(r[0]), dt(r[1]) + r[2:]) for r in cursor) 
all_values = np.asarray(filtered_rows, dtype=dtype) 

Для дальнейшего использования, вы можете использовать enumerate() для создания счетчика с петлей:

for r, row in enumerate(rows): 
    # r starts at 0 and counts along 
+0

Отлично, Благодарю. Если я затем выполним второй запрос сразу после этого, курсор сбрасывается правильно? – Dan

+0

Да, курсор сбрасывается с каждым новым '.execute()'. –

+0

Извините, просто добавил к вопросу. См. Мое редактирование. Могу ли я использовать такое понимание списков, чтобы получить структурированный массив вместо списка? – Dan

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