Seite 1 von 1

SqlAlchemy - ForeignKey Verständnisproblem

Verfasst: Freitag 4. Juni 2021, 13:55
von earloop
Hallo,

wenn ich das richtig verstanden habe, sorgt ein ForeignKey dafür, dass in der Child Tabelle (bei mir: comments) nur Werte eingegeben werden können, die in den Parent Tabellen enthalten sind. So stehts zumindest hier:
https://www.w3schools.com/sql/sql_foreignkey.asp

Ich habe 3 Tabellen: users, articles, comments
Jeder Comment hat nur einen User und nur einen Article, aber jeder Article kann viele Comments von vielen Nutzern haben.

Code: Alles auswählen

from sqlalchemy import Column, Integer, String, create_engine, ForeignKey
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

engine = create_engine('sqlite:///Database.db', echo = True)
Base = declarative_base()

#tables
class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    
class Article(Base):
    __tablename__ = 'articles'
    id = Column(Integer, primary_key=True)
    title = Column(String)
    content = Column(String)

class Comment(Base):
    __tablename__ = 'comments'
    id = Column(Integer, primary_key=True)
    comment = Column(String)
    article_id = Column(Integer, ForeignKey('articles.id'))
    user_id = Column(Integer, ForeignKey('users.id'))
    
Base.metadata.create_all(engine)

#session
Session = sessionmaker(bind = engine)
session = Session()

#fill tables
user1 = User(name = "user 1")
user2 = User(name = "user 2")
article1 = Article(title = 'title 1', content = 'lorem ipsum 1')
article2 = Article(title = 'title 2', content = 'lorem ipsum 2')
comment1 = Comment(comment = 'coment 1', article_id = 3, user_id = 4)

session.add_all([user1, user2, article1, article2, comment1])
session.commit()
Ich habe 2 user und 2 article angelegt, denen werden jeweils die ids 1 und 2 vergeben. Es gibt also in der ganzen Datenbank keine id, die größer als 2 ist. Trotzdem kann ich einen Comment anlegen, dessen foreign keys größer als 2 sind - diese sind also definitiv nicht vorhanden in den Partent Tabellen.
Ist das nicht ein Widerspruch zur ForeignKey constraint?

Re: SqlAlchemy - ForeignKey Verständnisproblem

Verfasst: Freitag 4. Juni 2021, 14:15
von kbr
Wenn ein Test auf Vorhandensein der Foreign-Keys erfolgen soll, dann musst Du das der Datenbank auch mitteilen, denn von alleine passiert das nicht. Dies geschieht beim Anlegen der Tabellen: https://docs.sqlalchemy.org/en/14/core/constraints.html

Re: SqlAlchemy - ForeignKey Verständnisproblem

Verfasst: Freitag 4. Juni 2021, 14:30
von earloop
Also mit nullable = False?
Auch wenn ich die Comment Klasse ändere:

Code: Alles auswählen

class Comment(Base):
    __tablename__ = 'comments'
    id = Column(Integer, primary_key=True)
    comment = Column(String)
    article_id = Column(Integer, ForeignKey('articles.id'), nullable = False)
    user_id = Column(Integer, ForeignKey('users.id'), nullable = False)
kann ich trotzdem Comments mit ids vergeben, die es im Parent nicht gibt.

Jetzt verstehe ich noch weniger. hier steht:
The FOREIGN KEY constraint prevents invalid data from being inserted into the foreign key column, because it has to be one of the values contained in the parent table.
Warum kann ich dann ids vergeben, die es im Parent nicht gibt?

und was ist der Unterschied zwischen:

Code: Alles auswählen

class Comment(Base):
    __tablename__ = 'comments'
    id = Column(Integer, primary_key=True)
    comment = Column(String)
    article_id = Column(Integer, ForeignKey('articles.id'))
    user_id = Column(Integer, ForeignKey('users.id'))
und

Code: Alles auswählen

class Comment(Base):
    __tablename__ = 'comments'
    id = Column(Integer, primary_key=True)
    comment = Column(String)
    article_id = Column(Integer)
    user_id = Column(Integer)
Welche Funktion hat das ForeignKey?

Re: SqlAlchemy - ForeignKey Verständnisproblem

Verfasst: Freitag 4. Juni 2021, 22:18
von DasIch
SQLite hat einige Besonderheiten, dazu gehört dass foreign keys nicht validiert werden, es sei den man stellt dass ein. Die SQLite Dokumention erklärt wie dass geht.

Re: SqlAlchemy - ForeignKey Verständnisproblem

Verfasst: Samstag 5. Juni 2021, 09:06
von earloop
Also macht es in diesem Fall überhaupt keinen Unterschied, ob ich die Spalte mit oder ohne ForeignKey definiere?

Re: SqlAlchemy - ForeignKey Verständnisproblem

Verfasst: Samstag 5. Juni 2021, 09:17
von __deets__
Du kannst es doch sinnvoll machen, indem du der Anleitung, die DasIch gepostet hat, folgst.

Aber ohne das zu machen offensichtlich: nein.