2016-08-02 17 views
0

Es gibt rund 5000 Unternehmen und jedes Unternehmen hat rund 4500 Preise, die insgesamt rund 22.000.000 Preise macht.Django-Datenbank zu postgresql

Jetzt eine Weile her, ich habe einen Code geschrieben, der diese Daten in einem Format wie this-

gespeichert
class Endday(models.Model): 
    company = models.TextField(null=True) 
    eop = models.CommaSeparatedIntegerField(blank=True, null=True, max_length=50000) 

und zu speichern, war- der Code

for i in range(1, len(contents)): 
    csline = contents[i].split(",") 
    prices = csline[1:len(csline)] 
    company = csline[0] 
    entry = Endday(company=company, eop=prices) 
    entry.save() 

Obwohl der Code war langsam (offensichtlich), aber es hat funktioniert und die Daten in der Datenbank gespeichert. Eines Tages beschloss ich, alle Inhalte von Endday zu löschen und versuchte erneut zu speichern. Aber es hat nicht funktioniert, mir einen Fehler Database locked zu werfen.

Wie auch immer, ich habe ein wenig recherchiert und erfahren, dass MySql mit so vielen Daten nicht umgehen kann. Wie wurde es überhaupt gespeichert? Ich kam zu dem Schluss, dass alle diese Preise am Anfang gespeichert wurden, nachdem die Menge in der Datenbank gespeichert wurde, damit diese nicht gespeichert wird.

Nach ein wenig Nachforschungen, habe ich erfahren, dass ich PostgreSql verwenden sollte, also habe ich die Datenbank geändert, Migrationen gemacht und bin weitergegangen, um den Code erneut zu versuchen, aber kein Glück. Ich habe einen Fehler Saying-

psycopg2.DataError: value too long for type character varying(50000) 

In Ordnung, also dachte ich, läßt versuchen bulk_create zu bedienen und modifizierte den Code ein wenig, aber ich war mit dem gleichen Fehler begrüßt.

Als nächstes dachte ich, vielleicht machen wir zwei Modelle, eines, um die Firmennamen und andere für die Preise und den Schlüssel zu diesem bestimmten Unternehmen zu halten. Also noch einmal, änderte es den Code-

class EnddayCompanies(models.Model): 
    company = models.TextField(max_length=500) 

class Endday(models.Model): 
    foundation = models.ForeignKey(EnddayCompanies, null=True) 
    eop = models.FloatField(null=True) 

Und die Aufrufe-

to_be_saved = [] 
for i in range(1, len(contents)): 
    csline = contents[i].split(",") 
    prices = csline[1:len(csline)] 
    company = csline[0] 
    companies.append(csline[0]) 
    prices =[float(x) for x in prices] 
    before_save = [] 
    for j in range(len(prices)): 
    before_save.append(Endday(company=company, eop=prices[j])) 
    to_be_saved.append(before_save) 
Endday.objects.bulk_create(to_be_saved) 

Aber zu meiner Überraschung, das war so langsam, dass in der Mitte, es hielt nur an einem Unternehmen. Ich habe versucht zu finden, die bestimmte Code wurde verlangsamt und es war-

before_save = [] 
    for j in range(len(prices)): 
    before_save.append(Endday(company=company, eop=prices[j])) 
    to_be_saved.append(before_save) 

Nun, jetzt bin ich wieder auf Platz eins, und ich kann nichts denken, so klingelte ich von SO. Die Fragen, die ich jetzt habe -

  • Wie geht das?
  • Warum funktioniert das Speichern mit MySql?
  • Gibt es einen besseren Weg, dies zu tun? (Natürlich muss es sein)
  • Wenn es ist, was ist es?
+0

Der Datenfehler, den Sie erhalten haben, ist, weil EOP länger als 50k Zeichen war, kein Problem mit der tatsächlichen Speicherung. Die gesperrte Datenbank könnte damit zu tun haben, wie Sie den Inhalt gelöscht haben (d. H. Wenn Sie dies mit einem separaten Prozess getan haben). – Sayse

+0

So ändern Sie es in 'TextField' tut es aber langsam und ineffektiv sowieso – ThatBird

+0

Während Sie eine sehr detaillierte Frage gemacht haben, ist es immer noch nicht eine vollständige MVCE. Wie sehen Ihre Eingabedaten aus? Auf andere Weise ist es viel zu weit gefasst. Es sind 3 oder 4 Fragen drin. Warum brichst du es nicht in verschiedene Fragen auf? – e4c5

Antwort

0

Ich glaube, Sie ein separates Modell für Company und Price etwas wie folgt erstellen:

class Company(models.Model): 
    name = models.CharField(max_length=20) 

class Price(models.Model): 
    company = models.ForeignKey(Company, related_name='prices') 
    price = models.FloatField() 

Dies ist, wie Sie die Daten speichern:

# Assuming that contents is a list of strings with a format like this: 
contents = [ 
    'Company 1, 1, 2, 3, 4...', 
    'Company 2, 1, 2, 3, 4...', 
    .... 
] 

for content in contents: 
    tokens = content.split(',') 
    company = Company.objects.create(name=tokens[0]) 
    Price.objects.bulk_create(
     Price(company=company, price=float(x.strip())) 
     for x in tokens[1:] 
    ) 
    # Then you can call prices now from company 
    company.prices.order_by('price') 

UPDATE: Ich habe gerade bemerkt, dass Es ist vergleichbar mit Ihrer zweiten Implementierung, der einzige Unterschied ist die Art der Speicherung der Daten. Meine Implementierung hat weniger Iterationen.

+0

Ich werde das versuchen und Sie wissen lassen – ThatBird

+0

@ ThatBird würde sich freuen, das Ergebnis zu wissen. :) –