Hallo! ich bin neu hier mit einem query-problem,
5 tabellen wie folgt a, b, c, d, e:
a: id, col1...
b: id, (foreign-key=a.id), col..
c: id, (foreign-key=a.id), col..
d: id, (foreign-key=b.id), col..
e: id, (foreign-key=c.id), col..
wie soll die abfrage auschauen, so dass auf jeden fall alle Einträge und zwar nicht wiederholt sondern korrect und identifizierbar drin sind?! danke
sqlalchemy-postgresql, join 5 tbl, f-key von einer in zwei
Hallo vielen dank für die Meldung! eine Abfrage, die alle tabellen joint unter a tabelle, d.h a hat ja fremd-key in b und c, b und c haben wiederum fremd-key in d und e.
ein resultat, die alle einträge von a-tabelle beinhaltet und darunter Einträge von b und c (zugeordnet zu a-id) und unter denen auch einträge von e und d (zugeordnet zu jeweils b-id , c-id)
ein resultat, die alle einträge von a-tabelle beinhaltet und darunter Einträge von b und c (zugeordnet zu a-id) und unter denen auch einträge von e und d (zugeordnet zu jeweils b-id , c-id)
- __blackjack__
- User
- Beiträge: 13191
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@rascha: Und das Problem ist jetzt genau welches? Man joint halt alle Tabellen und gut ist.
Code: Alles auswählen
...
print(
table_a.join(table_b)
.join(table_c)
.join(table_d)
.join(table_e)
.select()
.execute()
.fetchall()
)
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Hallo! vielen Dank für dein Input!__blackjack__ hat geschrieben: ↑Dienstag 13. April 2021, 16:06 @rascha: Und das Problem ist jetzt genau welches? Man joint halt alle Tabellen und gut ist.Code: Alles auswählen
... print( table_a.join(table_b) .join(table_c) .join(table_d) .join(table_e) .select() .execute() .fetchall() )
in sqlalchemy bin ich neu unterwegs. ich verwende db-session und zwar so:
database_url = "postgre_db_url"
engine = create_engine(
database_url
)
session_local = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
def get_db():
db = SessionLocal()
try:
yield db
except HTTPException:
db.close()
class A(Base):
__tablename__ = 'a'
id = Column(Integer, primary_key=True)
col1 = Column(String, nullable=False)
def example(db: Session = Depends(get_db)):
db.query(A).join(B).join(C).join(D).all()
und wenn ich da alles in dieser form wie du sagst joine , dann bekomme ich nur die a-tabelle!
l.g
- __blackjack__
- User
- Beiträge: 13191
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@rascha: Das ist nicht das gleiche. Du fragst `A` ab und joinst die anderen Tabellen, mein Code joint erst alle Tabellen und fragt die dann ab. Aber das funktioniert beim ORM ja sowieso alles komplett anders. Hättest Du ruhig erwähnen können das Du gar keine Tabellen abfragst sondern Objekte.
Was willst Du denn eigentlich machen hier? Wenn die Abhängigen Objekte generell gleich bei der ersten Abfrage mitgeladen werden sollen, oder nur in diesem speziellen Fall, dann kann man das an entsprechender Stelle angeben.
Edit: Wobei ich mich gerade Frage ob das was Du da machst, nicht auch schon das richtige macht. Was genau gefällt Dir an dem Ergebnis denn nicht?
Edit2: Warum willst Du das eigentlich machen? Premature optimization?
Was willst Du denn eigentlich machen hier? Wenn die Abhängigen Objekte generell gleich bei der ersten Abfrage mitgeladen werden sollen, oder nur in diesem speziellen Fall, dann kann man das an entsprechender Stelle angeben.
Edit: Wobei ich mich gerade Frage ob das was Du da machst, nicht auch schon das richtige macht. Was genau gefällt Dir an dem Ergebnis denn nicht?
Edit2: Warum willst Du das eigentlich machen? Premature optimization?
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Hi! kann sein, dass du den komplozierten Punkt hier ausser Acht gelassen hast? nämlich, dass f-key von a in b und c (i beiden) gibt.__blackjack__ hat geschrieben: ↑Dienstag 13. April 2021, 21:10 @rascha: Das ist nicht das gleiche. Du fragst `A` ab und joinst die anderen Tabellen, mein Code joint erst alle Tabellen und fragt die dann ab. Aber das funktioniert beim ORM ja sowieso alles komplett anders. Hättest Du ruhig erwähnen können das Du gar keine Tabellen abfragst sondern Objekte.
Was willst Du denn eigentlich machen hier? Wenn die Abhängigen Objekte generell gleich bei der ersten Abfrage mitgeladen werden sollen, oder nur in diesem speziellen Fall, dann kann man das an entsprechender Stelle angeben.
Edit: Wobei ich mich gerade Frage ob das was Du da machst, nicht auch schon das richtige macht. Was genau gefällt Dir an dem Ergebnis denn nicht?
Edit2: Warum willst Du das eigentlich machen? Premature optimization?
das resultat wird abhängig davon welche a-key jeweils in a oder b eingefügt wurde!
das macht es schwirig objecte entsprechend ohne wiederholungen unter a-tabelle zu bringen.
- __blackjack__
- User
- Beiträge: 13191
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@rascha: Das habe ich schon gesehen. `join()` funktioniert nicht. Aber a) einfach ``all_a = session.query(A).all()`` funktioniert, eben mit abfragen/nachladen wie es bei den `relationships()` definiert ist, und falls da der Standard definiert ist, also "select" beim Zugriff auf die Attribute, oder man gibt als Option bei der Abfrage an, dass alle `relationships()` per JOIN in der gleichen Abfrage geladen werden sollen: ``all_a = session.query(A).options(joinedload("*")).all()``. Beispiel, folgende Datenbank:
Variante 1:
Setzt beim `all()` eine SQL-Abfrage ab um die `A`-Objekte zu laden, und jeweils eine Abfrage für jeden Attributzugriff:
Variante 2:
Setzt *eine* SQL-Abfrage gleich beim `all()` ab:
Code: Alles auswählen
CREATE TABLE a (
id INTEGER NOT NULL,
value TEXT,
PRIMARY KEY (id)
);
INSERT INTO a VALUES(1,'a 1');
INSERT INTO a VALUES(2,'a 2');
CREATE TABLE b (
id INTEGER NOT NULL,
a_id INTEGER,
value TEXT,
PRIMARY KEY (id),
FOREIGN KEY(a_id) REFERENCES a (id)
);
INSERT INTO b VALUES(1,1,'b 1');
INSERT INTO b VALUES(2,2,'b 2');
CREATE TABLE c (
id INTEGER NOT NULL,
a_id INTEGER,
value TEXT,
PRIMARY KEY (id),
FOREIGN KEY(a_id) REFERENCES a (id)
);
INSERT INTO c VALUES(1,1,'c 1');
INSERT INTO c VALUES(2,2,'c 2');
CREATE TABLE d (
id INTEGER NOT NULL,
b_id INTEGER,
value TEXT,
PRIMARY KEY (id),
FOREIGN KEY(b_id) REFERENCES b (id)
);
INSERT INTO d VALUES(1,1,'d 1');
INSERT INTO d VALUES(2,2,'d 2');
CREATE TABLE e (
id INTEGER NOT NULL,
c_id INTEGER,
value TEXT,
PRIMARY KEY (id),
FOREIGN KEY(c_id) REFERENCES c (id)
);
INSERT INTO e VALUES(1,1,'e 1');
INSERT INTO e VALUES(2,2,'e 2');
Code: Alles auswählen
all_a = session.query(A).all()
a = all_a[0]
print(a.value, a.b.value, a.c.e.value)
Code: Alles auswählen
-- all()
SELECT a.id AS a_id, a.value AS a_value FROM a
-- a.b
SELECT b.id AS b_id, b.a_id AS b_a_id, b.value AS b_value
FROM b
WHERE ? = b.a_id
-- a.c
SELECT c.id AS c_id, c.a_id AS c_a_id, c.value AS c_value
FROM c
WHERE ? = c.a_id
-- c.e
SELECT e.id AS e_id, e.c_id AS e_c_id, e.value AS e_value
FROM e
WHERE ? = e.c_id
Variante 2:
Code: Alles auswählen
all_a = session.query(A).options(joinedload("*")).all()
a = all_a[0]
print(a.value, a.b.value, a.c.e.value)
Code: Alles auswählen
SELECT a.id AS a_id, a.value AS a_value, b_1.id AS b_1_id, b_1.a_id AS b_1_a_id,
b_1.value AS b_1_value, d_1.id AS d_1_id, d_1.b_id AS d_1_b_id,
d_1.value AS d_1_value, c_1.id AS c_1_id, c_1.a_id AS c_1_a_id,
c_1.value AS c_1_value, e_1.id AS e_1_id, e_1.c_id AS e_1_c_id,
e_1.value AS e_1_value
FROM a
LEFT OUTER JOIN b AS b_1 ON a.id = b_1.a_id
LEFT OUTER JOIN d AS d_1 ON b_1.id = d_1.b_id
LEFT OUTER JOIN c AS c_1 ON a.id = c_1.a_id
LEFT OUTER JOIN e AS e_1 ON c_1.id = e_1.c_id
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
@__blackjack__ Hi! das funktioniert, ich hatte schon die relationships verwendet aber von allen 3 objecten in
form von session.query(a, b, c).options(joinload(a.b_relatin),joinload(a.c_relatin),joinload(b.d_relation),joinload(c.e_relation)).all()
es hat aber nur richtig funktioniert solange b und c die selben f-key's von a hatten sonst war es konflikt!
aber deine Methode session.query(A).options(joinedload("*")).all() habe ich probiert und kein Konflikt.
super herzlichen Dank! L.G
form von session.query(a, b, c).options(joinload(a.b_relatin),joinload(a.c_relatin),joinload(b.d_relation),joinload(c.e_relation)).all()
es hat aber nur richtig funktioniert solange b und c die selben f-key's von a hatten sonst war es konflikt!
aber deine Methode session.query(A).options(joinedload("*")).all() habe ich probiert und kein Konflikt.
super herzlichen Dank! L.G