ubuntuusers.de

Python3, SQLite und Foreign Keys Mismatch

Status: Gelöst | Ubuntu-Version: Ubuntu 18.04 (Bionic Beaver)
Antworten |

Glocke

Avatar von Glocke

Anmeldungsdatum:
1. März 2009

Beiträge: 880

Wohnort: Thüringen

Hallo,

ich versuche ein einfaches Foreign-Key Constraint in meiner SQLite-DB zu nutzen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/usr/bin/python3

import sqlite3

db  = sqlite3.connect('') # inmemory-DB
cur = db.cursor()

# Aktiviert Foreign Keys
cur.execute("PRAGMA foreign_keys=ON")

# Check, dass aktiv
cur.execute("PRAGMA foreign_keys")
print(cur.fetchall())

# Tabelle B verweist auf A
# rowid wird automatisch als PK deklariert
cur.execute("create table A ( name varchar(50) )")
cur.execute("create table B ( A_id int, foreign key (A_id) references A (rowid) )")

cur.execute("insert into A (name) values ('foo')")

db.commit()

# es gibt definitiv einen A-Eintrag mit rowid=1
cur.execute("select rowid from A")
print(cur.fetchall())

# führt zum Fehler, obwohl es in A den Eintrag gibt
cur.execute("insert into B (A_id) values (1)")

Tabelle B soll einen Foreign Key auf den PK von Tabelle A verwenden. (Der PK von A wird als rowid automatisch generiert, ich kann ihn auch abfragen).

Ausgabe:

[(1,)]
[(1,)]
Traceback (most recent call last):
  File "dbtest.py", line 26, in <module>
    cur.execute("insert into B (A_id) values (1)")
sqlite3.OperationalError: foreign key mismatch - "B" referencing "A"

Was mache ich falsch? Verzichte ich auf das enable der Foreign Keys, fehlt jegliche Integritätsprüfung (ich kann dann auch eine 13 als Wert verwenden obwohl es keinen solchen A-Eintrag gibt....)

Btw:

1
2
3
4
5
6
Python 3.6.7 (default, Oct 22 2018, 11:32:17) 
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sqlite3
>>> print(sqlite3.version)
2.6.0

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13174

Glocke schrieb:

Was mache ich falsch?

Es ist illegal, dass Du auf "rowid" referenzierst: "The parent key must be a named column or columns in the parent table, not the rowid." Quelle). Das ist eine automatisch generierte ID von Sqlite. Du willst ja die Integrität der Daten sicherstellen.

noisefloor Team-Icon

Anmeldungsdatum:
6. Juni 2006

Beiträge: 29567

Hallo,

es macht übrigens bei Python oft Sinn, ein ORM zu nutzen (außer bei mega-trivialen Sachen). SQLAlchemy ist DAS ORM für Python, eine kleinere Alternative ist PeeWee.

Gruß, noisefloor

Glocke

(Themenstarter)
Avatar von Glocke

Anmeldungsdatum:
1. März 2009

Beiträge: 880

Wohnort: Thüringen

rklm schrieb:

Glocke schrieb:

Was mache ich falsch?

Es ist illegal, dass Du auf "rowid" referenzierst: "The parent key must be a named column or columns in the parent table, not the rowid." Quelle). Das ist eine automatisch generierte ID von Sqlite. Du willst ja die Integrität der Daten sicherstellen.

Danke, hatte ich glatt übersehen!

noisefloor schrieb:

Hallo,

es macht übrigens bei Python oft Sinn, ein ORM zu nutzen (außer bei mega-trivialen Sachen). SQLAlchemy ist DAS ORM für Python, eine kleinere Alternative ist PeeWee.

Gruß, noisefloor

Da hast du vollkommen recht, bin inzwischen auf "Pony" gegangen.

Antworten |