2013-04-27 55 views
1

我下載一個很大的CSV文件遙遠,想推都行到MySQL,因爲他們進來。我用csv.reader解析遙遠的文件。我將1000行批量添加到MySQL中。下載一個文件,並推到MySQL不會超時在Python

問題是與對等端的連接在5分鐘後超時,儘管文件可能在不到一分鐘內下載,但推入MySQL需要更多的時間。

有沒有辦法有下載任務和異步工作,所以與對端的連接不會等待MySQL的約束推工作?

我想避免

  1. 下載在內存中的完整文件,如果沒有必要
  2. 起儘快推入MySQL作爲第一線下載不必亂
  3. 與臨時文件

基本上,我希望我的python腳本可以做類似curl file | my_script_that_pushes_values.sh的事情。

這裏是我做的一個例證:

csvReader = csv.reader(distantfile) 
valuesBuffer = [] 
for row in csvReader: 
    valuesBuffer.append(getValues(row)) 
    if len(valuesBuffer) % 1000 = 0: 
    pushValuesIntoMySQL(valuesBuffer) 
    valuesBuffer = [] 
pushValuesIntoMySQL(valuesBuffer) 

回答

2

我將整個文件複製到服務器,然後使用LOAD DATA LOCAL INFILE,因爲它支持CSV輸入:

LOAD DATA INFILE 'data.txt' INTO TABLE tbl_name 
    FIELDS TERMINATED BY ',' ENCLOSED BY '"' 
    LINES TERMINATED BY '\r\n' 
    IGNORE 1 LINES; 

如果您不喜歡這種解決方案,你可以使用mysql_ping()(希望你使用的連接器支持它)到汽車重新連接。

檢查與服務器的連接是否正常工作。如果連接斷開並且啓用了自動重新連接,則嘗試重新連接。如果連接關閉並且自動重新連接被禁用,mysql_ping()返回一個錯誤。


如果你有問題你可以下載文件,但它超時因爲MySQL的延遲,你可以在two threads運行並實現同步槽queue

# Prepare queue and end signaling handler 
q = queue.Queue() 
done = threading.Event() 

# Function that fetches items from q and puts them into db after 
# certain amount is reached 
def store_db(): 
    items=[] 

    # Until we set done 
    while not done.is_set(): 
     try: 
      # We may have 500 records and thread be done... prevent deadlock 
      items.append(q.get(timeout=5)) 
      if len(items) > 1000: 
       insert_into(items) 
       items = [] 
      q.task_done() 
     # If you wait longer then 5 seconds < exception 
     except queue.Empty: pass 

    if items: 
     insert_into(items) 

# Fetch all data in a loop 
def continous_reading(): 
    # Fetch row 
    q.put(row) 

# Start storer thread 
t = threading.Thread(target=store_db) 
t.daemon = True 
t.start() 

continous_reading() 
q.join() # Wait for all task to be processed 
done.set() # Signal store_db that it can terminate 
t.join() # to make sure the items buffer is stored into the db 
+0

謝謝,不幸的是,它不會在我的情況下工作。超時時間與服務於csv的遠程服務器有關,我無法控制它,而不是使用我的MySQL數據庫。另外,我需要在CSV中進行一些後處理,然後再推送(在我的示例中隱藏在'getValues()'中)。 – 2013-04-27 21:43:57

+0

@MadEchet希望這個編輯能涵蓋它 – Vyktor 2013-04-27 21:58:12

+0

正是我在找的東西,謝謝! – 2013-04-28 06:56:24