2017-09-22 5 views
0

Ich arbeite an einer Videospiel-Auktionswebsite für den Kauf/Verkauf von In-Game-Artikeln. Ich möchte in der Lage sein, die Auktionstabelle abzufragen und sie nach den "heißesten" Auktionen zu sortieren. Dies basiert auf der Anzahl der Gebote/Stunde, die auf einer Auktion platziert wurden.Abfrage nach Anzahl der One-to-Many-Beziehungen pro Stunde - SQLAlchemy

Hier ist das Auktionsmodell:

class Auctions(db.Model): 
    id = db.Column(db.Integer, primary_key=True, index=True) 
    posted = db.Column(db.DateTime()) 
    end = db.Column(db.DateTime()) 
    ... 

    bids = db.relationship('Bids', backref='auctions', lazy='dynamic', order_by='desc(Bids.amount)', cascade="all, delete-orphan") 

Hier ist das Modell Gebote:

class Bids(db.Model): 
    id = db.Column(db.Integer, primary_key=True, index=True) 
    bidder_id = db.Column(db.Integer, db.ForeignKey('user.id'), index=True) 
    auction_id = db.Column(db.Integer, db.ForeignKey('auctions.id'), index=True) 
    amount = db.Column(db.Integer) 
    posted = db.Column(db.DateTime()) 

Ich bin in der Lage, sie durch die Höhe der Gebote wie diese zu sortieren:

hot_stmt = db.session.query(models.Bids.auction_id, func.count('*').label('bid_count')).group_by(models.Bids.auction_id).subquery() 
hot = db.session.query(models.Auctions, hot_stmt.c.bid_count).outerjoin(hot_stmt, (models.Auctions.id == hot_stmt.c.auction_id)).order_by(hot_stmt.c.bid_count.desc()).limit(5) 

Ich kann damit Gebote/Stunde berechnen und auflisten:

for auc, count in hot: 
    time_delta = datetime.utcnow() - auc.posted 
    auc_hours = time_delta.seconds/60/60 
    print(auc.id, count/auc_hours) 

Wie könnte ich die Abfrage nach Geboten/Stunde sortieren, sodass die Abfrage die Top 5 der heißesten Auktionen zurückgibt?

Antwort

1

Ein nützlicher Ansatz ist ein Wörterbuch mit Auktionen als Schlüssel und Gebote/h als Werte zu schaffen:

d = {} 
for auc, count in hot: 
    time_delta = datetime.utcnow() - auc.posted 
    auc_hours = time_delta.seconds/60/60 
    d[auc] = count/auc_hours 

eine Liste der Auktion Marke:

aucs = [auc for auc, count in hot] 

Sortieren Sie die Liste aucs basierend auf die Werte (verwenden Sie das umgekehrte Schlüsselwort, um die höchsten Werte am Anfang der Liste zu setzen, da die Sortierfunktion standardmäßig vom niedrigsten zum höchsten Wert geht):

aucs.sort(key=d.get, reverse=True) 
+0

Vielen Dank für die Antwort! Ich war nicht klar in meinem ursprünglichen Beitrag. Ich möchte die Abfrage die Top 5 heißesten Auktionen zurückgeben, so muss die Bestellung mit SQLAlchemy getan werden, so dass ich einfach die Abfrage auf die Top 5 zu begrenzen. Dies würde funktionieren, wenn ich nur die Auktionstabelle für alle abfragen aktuelle Auktionen und sortiere es dann so, ich mache mir nur Sorgen um die Leistung. – triggdev

+1

Ich bin mir praktisch sicher, dass die 'list.sort'-Funktion in C geschrieben ist und ziemlich schnell ist. Es wäre einfach zu versuchen und zu sehen, ob die Leistung akzeptabel ist. –

+0

Ich bin hauptsächlich besorgt über die Belastung der Datenbank. Ich weiß nicht viel über den Leistungsunterschied zwischen den beiden. Ich würde denken, 1000+ Ergebnisse zurückgeben und dann Sortierung/Trimmen wäre langsamer als die Rückgabe von 5 Ergebnissen in einer bereits sortierten Abfrage. – triggdev

Verwandte Themen