SQLAlchemy upsert Function für MySQL Db implementieren

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
Bird3000
User
Beiträge: 2
Registriert: Montag 8. Februar 2021, 16:54

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)
        ...
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

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.
Bird3000
User
Beiträge: 2
Registriert: Montag 8. Februar 2021, 16:54

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()
Antworten