2017-08-07 1 views
0

Ich habe gerade erst begonnen Python, aber habe in den letzten Monaten viel gelernt, jetzt habe ich eine Wand über das Aktualisieren von Objekten auf einem Modell mit einer guten Geschwindigkeit getroffen.Python/Django vergleichen und aktualisieren Modellobjekte

Ich habe ein Modell namens Produkte und das ist aus einer CSV-Datei befüllt, jeden Tag diese Datei mit Änderungen wie Kosten und Menge aktualisiert, kann ich jede Zeile der Datei mit dem Produktmodell vergleichen, aber mit 120k Zeilen dies dauert 3-4 Stunden.

Welchen Prozess kann ich machen, um diesen Prozess diese Datei schneller zu machen. Ich möchte nur die Objekte ändern, wenn sich die Kosten und die Menge geändert haben

Irgendwelche Vorschläge, wie ich das angehen?

Ver3 von dem, was ich versucht habe.

from django.core.management import BaseCommand 
from multiprocessing import Pool 
from django.contrib.auth.models import User 
from pprint import pprint 
from CentralControl.models import Product, Supplier 
from CentralControl.management.helpers.map_ingram import * 
from CentralControl.management.helpers.helper_generic import * 
from tqdm import tqdm 

from CentralControl.management.helpers.config import get_ingram 
import os, sys, csv, zipfile, CentralControl 

# Run Script as 'SYSTEM' 
user = User.objects.get(id=1) 

# Get Connection config. 
SUPPLIER_CODE, FILE_LOCATION, FILE_NAME = get_ingram() 


class Command(BaseCommand): 
def handle(self, *args, **options): 
    list_in = get_file() 
    list_current = get_current_list() 

    pool = Pool(6) 

    pool.map(compare_lists(list_in, list_current)) 

    pool.close() 



def compare_lists(list_in, list_current): 
    for row_current in tqdm(list_current): 
     for row_in in list_in: 
      if row_in['order_code'] == row_current['order_code']: 

       #do more stuff here. 

       pass 

def get_current_list(): 
    try: 
     supplier = Supplier.objects.get(code='440040') 
     current_list = Product.objects.filter(supplier=supplier).values() 
     return current_list 
    except: 
     print('Error no products with supplier') 
     exit() 


def get_file(): 
    with zipfile.ZipFile(FILE_LOCATION + 'incoming/' + FILE_NAME, 'r') as zip: 
    with zip.open('228688 .csv') as csvfile: 
     reader = csv.DictReader(csvfile) 
     list_in = (list(reader)) 

     for row in tqdm(list_in): 
      row['order_code'] = row.pop('Ingram Part Number') 
      row['order_code'] = (row['order_code']).lstrip("0") 
      row['name'] = row.pop('Ingram Part Description') 
      row['description'] = row.pop('Material Long Description') 
      row['mpn'] = row.pop('Vendor Part Number') 
      row['gtin'] = row.pop('EANUPC Code') 
      row['nett_cost'] = row.pop('Customer Price') 
      row['retail_price'] = row.pop('Retail Price') 
      row['qty_at_supplier'] = row.pop('Available Quantity') 
      row['backorder_date'] = row.pop('Backlog ETA') 
      row['backorder_date'] = (row['backorder_date']) 
      row['backorder_qty'] = row.pop('Backlog Information') 

     zip.close() 
     #commented out for dev precess. 
     #os.rename(FILE_LOCATION + 'incoming/' + FILE_NAME, FILE_LOCATION + 'processed/' + FILE_NAME) 
     return list_in 
+1

Wie können wir die Effizienz von Code verbessern, den wir noch nie gesehen haben? Veröffentlichen Sie, was Sie getan haben und lassen Sie uns sehen, wo es falsch ist –

+0

Sie können Hashing verwenden, um zwei Objekte schnell auf Unterschiede zu vergleichen. Sie können damit den Objektvergleich beschleunigen. Eine Alternative wäre, jeden Tag die CSV-Datei zu vergleichen und nur die Zeilen zu extrahieren, die sich für die Aktualisierung geändert haben. – pypypy

+0

'120k Linien dauert dies 3-4 Stunden.Sie erwarten sicherlich zu viel. Es kann nicht so lange dauern. Wenn Sie so viele Daten verarbeiten müssen, als ich mit einigen Aufgabenläufern wie Sellerie vorschlagen würde. –

Antwort

0

Ich habe einmal ein Problem der langsamen Last von Daten konfrontiert, kann ich Ihnen sagen, was ich kann es Ihnen vielleicht hätte irgendwie helfen, habe ich die Ausführung zu dem Debug-Modus und versuchte, weicht colomn, um herauszufinden, wird die Verursachung langsames Laden, und jedes Mal, wenn ich sehe, dass ein colomn das Problem verursacht, füge ich einen Index hinzu (in der SGBD -> postgreSQL in meinem Fall), und es hat funktioniert. Ich hoffe, dass Sie vor dem gleichen Problem stehen, so dass meine Antwort Ihnen helfen kann.

0

Hier ist es grobe Idee: 1, wenn csv Lesen, Verwendung Pandas als vorschlagen, durch @BearBrow in array_csv 2, die obj Daten von Django in Numpy arrary konvertieren array_obj 3, nicht vergleichen sie eins nach dem anderen, numpy Substraktion mit

compare_index = (array_csv[['cost',['quantity']]] - array[['cost',['quantity']]] == 0) 

4, finden die aktualisierte Spalte obj_need_updated = array_obj [np.logic_any (compare_index [ 'Kosten'], vergleichen [ 'Menge'])]

dann Update Django Bulk verwenden https://github.com/aykut/django-bulk-update zu Massenaktualisierung

Hoffe, dies wird Ihnen Hinweise geben, um Ihren Code zu beschleunigen

+0

Dies ist ein Riss. aber einen Fehler bekommen. 'code' def GET_FILE(): mit zipfile.ZipFile (FILE_LOCATION + 'incoming /' + FILE_NAME, 'r') als ZIP: mit zip.open ('228688 CSV') als csvfile: list_in = pd.read_csv (csvfile) print (list_in) pandas.errors.ParserError: Fehler beim Token von Daten. C-Fehler: Erwartete 40 Felder in Zeile 33967, sah 41 – flammable

+0

@flammbar scheint es die Daten in 228688.csv ist nicht konsistent, können Sie Zeile 33967 überprüfen, der Fehler sagte, dass Zeile 41 Felder hat, während andere Zeile hat 40 Felder – wllbll

+0

Yeah Ich habe darüber gelesen und error_bad_lines = False hinzugefügt. :) – flammable

Verwandte Themen