Ich habe viele Model-Klassen mit Beziehungen zwischen ihnen mit einer CRUD-Schnittstelle zu bearbeiten. Das Problem besteht darin, dass einige Objekte nicht gelöscht werden können, da andere Objekte auf sie verweisen. Manchmal kann ich eine ON DELETE-Regel einrichten, um diesen Fall zu behandeln, aber in den meisten Fällen möchte ich nicht automatisch verwandte Objekte löschen, bis sie manuell gelöst werden. Wie auch immer, ich möchte dem Redakteur eine Liste von Objekten vorstellen, die sich auf das aktuell angezeigte beziehen, und diejenigen hervorheben, die das Löschen aufgrund der FOREIGN KEY-Einschränkung verhindern. Gibt es eine fertige Lösung, um Referer automatisch zu erkennen?
Aktualisieren
Die Aufgabe scheint sehr häufig zu sein (z. B. django ORM zeigt alle Abhängigkeiten), so dass ich mich wundere, dass es noch keine Lösung dafür gibt.
Es gibt zwei Richtungen vorgeschlagen:
backref
. Aber es gibt keine Garantie, dass alle Relationen backref
definiert haben. Darüber hinaus gibt es Fälle, in denen backref
bedeutungslos ist. Obwohl ich es überall definieren kann, mag ich es nicht so und es ist nicht zuverlässig. MetaData
object und sammle Abhängigkeiten von ihrer foreign_keys
Eigenschaft (der Code von sqlalchemy_schemadisplay kann als Beispiel verwendet werden, dank stephans Kommentaren. Dies ermöglicht es, alle Abhängigkeiten zwischen -Tabellen zu erfassen, aber was ich brauche, sind Abhängigkeiten zwischen Modellklassen . Einige Fremdschlüssel sind in Zwischentabellen definiert und weisen keine ihnen entsprechenden Modelle auf (in Beziehungen als secondary
verwendet). Klar, ich kann weiter gehen und verwandtes Modell finden (muss noch einen Weg finden, es zu tun), aber es sieht zu kompliziert aus. Lösung
Unten ist eine Methode der Basismodellklasse (für die deklarative Erweiterung), die ich als Lösung verwende. Es ist nicht perfekt und erfüllt nicht alle meine Anforderungen, aber es funktioniert für den aktuellen Stand meines Projekts. Das Ergebnis wird als Wörterbuch von Wörterbüchern gesammelt, sodass ich sie nach Objekten und ihren Eigenschaften gruppiert darstellen kann. Ich habe noch nicht entschieden, ob es eine gute Idee ist, da die Liste der Referer manchmal riesig ist und ich gezwungen bin, sie auf eine vernünftige Anzahl zu beschränken.
%Vor%Danke an alle, die mir geholfen haben, besonders an Stephan und van.
SQL: Ich stimme absolut nicht mit S.Lott ' Antwort .
Ich kenne keine Out-of-the-Box-Lösung, aber es ist definitiv möglich , alle Tabellen zu ermitteln, die ForeignKey-Einschränkungen für eine bestimmte Tabelle haben. Man muss die INFORMATION_SCHEMA
Ansichten wie REFERENTIAL_CONSTRAINTS
, KEY_COLUMN_USAGE
, TABLE_CONSTRAINTS
usw. richtig verwenden. Siehe SQL Server-Beispiel . Mit einigen Einschränkungen und Erweiterungen unterstützen die meisten Versionen neuer relationaler Datenbanken INFORMATION_SCHEMA
standard. Wenn Sie alle FK-Informationen und das Objekt (Zeile) in der Tabelle haben, müssen einige SELECT
-Anweisungen ausgeführt werden, um alle anderen Zeilen in anderen Tabellen zu erhalten, die sich auf die angegebene Zeile beziehen und verhindern, dass sie gelöscht wird. p>
SqlAlchemy: Wie von stephan in seinem Kommentar erwähnt, sollte es ziemlich einfach für Sie sein, wenn Sie orm
mit backref
für Relationen verwenden die Liste der übergeordneten -Objekte, die den Verweis auf das Objekt behalten, das Sie löschen möchten, da diese Objekte grundsätzlich zugeordnete Eigenschaften Ihres Objekts sind ( child1.Parent
).
Wenn Sie mit Table
Objekten von sql alchemy arbeiten (oder nicht immer backref
für Relationen verwenden), müssten Sie Werte von foreign_keys
für alle Tabellen und dann für all diese ForeignKey
erhalten s Rufen Sie references(...)
method auf und stellen Sie Ihre Tabelle als Parameter zur Verfügung. Auf diese Weise finden Sie alle FKs (und Tabellen), die sich auf die Tabelle beziehen, der Ihr Objekt zugeordnet ist. Dann können Sie alle Objekte abfragen, die auf Ihr Objekt verweisen, indem Sie die Abfrage für jede dieser FKs erstellen.
Im Allgemeinen gibt es keine Möglichkeit, alle der Referenzen in einer relationalen Datenbank zu entdecken.
In einigen Datenbanken können sie deklarative referenzielle Integrität in Form von expliziten Fremdschlüssel- oder Prüfbedingungen verwenden.
Aber das ist nicht erforderlich. Es kann unvollständig oder inkonsistent sein.
Jede Abfrage kann eine FK-Beziehung enthalten, die nicht deklariert ist. Ohne das Universum aller Abfragen können Sie nicht wissen, welche Beziehungen verwendet, aber nicht deklariert werden.
Um "Referer" im Allgemeinen zu finden, müssen Sie das Datenbankdesign kennen und alle Abfragen haben.
Für jede Modellklasse können Sie leicht sehen, ob alle ihre Eins-zu-Viele-Beziehungen leer sind, indem Sie einfach nach der Liste fragen und sehen, wie viele Einträge sie enthält. (Es gibt wahrscheinlich auch einen effizienteren Weg, der in Bezug auf COUNT implementiert wird.) Wenn es Fremdschlüssel für das Objekt gibt und Sie Ihre Objektbeziehungen korrekt eingerichtet haben, dann wird mindestens eine dieser Listen ungleich Null sein in Länge.
Tags und Links python sqlalchemy orm