Seite 1 von 1

SQLAlchemy upsert Function für MySQL Db implementieren

Verfasst: Montag 8. Februar 2021, 17:18
von Bird3000
Ich habe die folgende Dokumentation als Leitfaden verwendet und versucht, einen Upsert mechanismus für meine Tabelle Team zu implementieren. Ich möchte in der Lage sein, alle Spalten der ausgewählten Tabelle auf einmal dynamisch zu aktualisieren (ohne jede Spalte einzeln angeben zu müssen). Ich habe verschiedene Ansätze ausprobiert, aber keiner hat eine richtige SQL-Abfrage geliefert, die ausgeführt werden kann. Was habe ich falsch verstanden bzw. was sind die Fehler im Code?

https://docs.sqlalchemy.org/en/12/diale ... ate-upsert

https://github.com/sqlalchemy/sqlalchemy/issues/4483

Code: Alles auswählen

class Game(CustomBase, Base):
        __tablename__ = 'games'
    
        game_id = Column('id', Integer, primary_key=True)
        date_time = Column(DateTime, nullable=True)
        hall_id = Column(Integer, ForeignKey(SportPlace.id), nullable=False)
    
        team_id_home = Column(Integer, ForeignKey(Team.team_id))
        team_id_away = Column(Integer, ForeignKey(Team.team_id))
        score_home = Column(Integer, nullable=True)
        score_away = Column(Integer, nullable=True)
    
        ...

    def put_games(games): # games is a/must be a list of type Game
    
        insert_stmt = insert(Game).values(games)
        #insert_stmt = insert(Game).values(id=Game.game_id, data=games)
        
        on_upset_stmt = insert_stmt.on_duplicate_key_update(**games)

        print(on_upset_stmt)
        ...

Re: SQLAlchemy upsert Function für MySQL Db implementieren

Verfasst: Montag 8. Februar 2021, 21:24
von sparrow
Zum Verständnis: Warum machst du das so kompliziert? Wenn du doch eh Game-Objekte hast, kannst du die doch einfach modifizieren und speichern. Dafür ist der ORM-Mapper doch da.

Re: SQLAlchemy upsert Function für MySQL Db implementieren

Verfasst: Dienstag 9. Februar 2021, 10:30
von Bird3000
Hallo @sparrow

Mmm ich weis nicht ob das für meinen Anwendungsfall auch geht. Konkret lade ich regelmässig Originaldaten von einer externen API (ink. ID) und möchte damit meine Datenbank aktualisieren, also die bestehenden Einträge (mit gleicher ID) mit den neuen Daten updaten und fehlende ergänzen. Ich kann sie aber nicht komplett neu laden, weil es Abhängigkeiten und zusätzliche Parameter gibt, bez. ich nicht immer die ganze Tabelle sondern nur einzelne Zeilen neu laden möchte, um die Anzahl Zugriffe auf die API minimal halten muss. Ich habe in Erinnerung, dass es mir jeweils Fehler angezeigt hat, wenn ich die bestehende Tabelle mit einem neuen Eintrag mit der gleichen ID ergänzen wollte. Vielleicht habe ich das aber auch falsch implementiert. Ich wäre natürlich sehr glücklich, wenn es sogar eine einfachere, allgemeinere Lösung gäbe ohne diesen MySQL spezifischen Befehl on_duplicate_key_update. Ich hoffe, dass hat deine Frage beantwortet.

Code: Alles auswählen

result = Game(game_id=game.game_id, date_time=datetime.strptime(f"{game.date} {game.time}", "%d.%m.%Y %H:%M"), ...)
session.add(result)
session.commit()