SQLAlchemy, Vererbung und one-to-one-Relationship

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
paddie
User
Beiträge: 101
Registriert: Donnerstag 11. Oktober 2018, 18:09

Ich habe hier unter anderem folgende Klassen:

Code: Alles auswählen

class Product(db.Model):
    __tablename__ = 'product'
    id = db.Column(db.Integer, primary_key=True)
    item_id = db.Column(db.String(100), unique=True)
    ...
    
    type = db.Column(db.String(50))

    __mapper_args__ = {
        'polymorphic_on': "type"
    }

Code: Alles auswählen

class Lamp(Product):
    __tablename__ = 'lamp'
    id = db.Column(db.Integer, ForeignKey(Product.id), primary_key=True)
    ...
    
    ---neu---
    light_source = db.relationship("LightSource", uselist=False, back_populates="lamp")
    ---neu---
    
    __mapper_args__ = {
        'polymorphic_identity': 'lamp'
    }
Jetzt wollte ich diese Klasse hinzufügen:

Code: Alles auswählen

class LightSource(db.Model):
    __tablename__ = 'light_source'
    id = db.Column(db.Integer, ForeignKey(Lamp.id), primary_key=True)
    lamp = relationship("Lamp", uselist=False, back_populates="light_source")
    ...
    data = db.Column(db.String(40)

Ich mache also ein

Code: Alles auswählen

new_lamp = Lamp(item_id='blub')

new_light_source = LightSource(data='blabla')

new_lamp.light_source = new_light_source
Jetzt bekomme ich, wenn ich ein Lamp-Objekt committen will folgenden Fehler:

Code: Alles auswählen

sqlalchemy.exc.IntegrityError: (psycopg2.errors.NotNullViolation) null value in column "id" violates not-null constraint
Sobald ich das LightSource Objekt weglasse funktionierts :roll: :roll:.

Kann mir vielleicht jemand sagen WO ich hier den Fehler mache?

Danke
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Es wäre sinnvoll den Code zu haben der tatsächlich zu der Exception geführt hat, so ist es schwierig dir zur helfen.

Davon mal abgesehen würde ich dir empfehlen keine Vererbung zu nutzen. Relationelle Datenbanken funktionieren so einfach nicht und du wirst langfristig nicht glücklich damit werden gegen die Datenbank zu arbeiten.
paddie
User
Beiträge: 101
Registriert: Donnerstag 11. Oktober 2018, 18:09

hm, ok, das hätte ich natürlich auch noch dabei schreiben können :roll:

Code: Alles auswählen

    db.session.add(new_lamp)
    db.session.commit()
Wenn ich das

Code: Alles auswählen

    new_lamp.light_source = new_light_source
weglasse funktionierts ohne Probleme.

Den zweiten Absatz verstehe ich nicht wirklich. Bei welchem Punkt arbeite ich denn gegen die DB? OK, ich hätte auch für jeden Product-Type eine eigene Table anlegen können, aber das kam mir irgendwie "falsch" vor. Ich hätte ja dann mehrere Tables in denen dann die selben Daten (die des Product-Objects) liegen würden.
In meinem Fall habe ich jetzt eine Table (product) mit den allgemeinen Produkt-Daten die bei allen Produkten benötigt werden und dann eine Table (z. B. lamp) mit den spezifischen Daten für diesen Produkttyp.
stacklikemind
User
Beiträge: 1
Registriert: Sonntag 23. Mai 2021, 15:02

Code: Alles auswählen

sqlalchemy.exc.IntegrityError: (psycopg2.errors.NotNullViolation) null value in column "id" violates not-null constraint
Du hast eine Tabelle manuell erstellt. Dabei legt komischerweise postgresql keine Sequence Nummer an, die es braucht um eine Zahl ID zu zu weisen und diese automatisch zu inkrementieren.

Du musst hierfür eine Sequence erstellen und dieser dann der ID hinzufügen. Dann ist ID auch nicht mehr NULL.

Hier in dem Stackexchange Link findest du unter der akzeptierten Antwort einen Guide wie man das mit pgAdmin nachholen kann.
https://dba.stackexchange.com/question ... in/119633
Antworten