2016-08-05 99 views
0

Ich habe ein Problem mit Fremdschlüssel in Flask. Mein Modell ist folgende:Kolben Fremdschlüsseleinschränkung

Model.py

class User(db.Model): 

    __tablename__ = "users" 
    __table_args__ = {'extend_existing': True} 
    user_id = db.Column(db.BigInteger, primary_key=True) 
    # EDIT 
    alerts = db.relationship('Alert', backref='user', lazy='dynamic') 

    def __init__(self, user_id): 
     self.user_id = user_id 


class Alert(db.Model): 

    __tablename__ = 'alert' 
    __table_args__ = {'extend_existing': True} 
    alert_id = db.Column(db.Integer, primary_key=True, autoincrement=True) 
    user_id = db.Column(db.BigInteger, db.ForeignKey('users.user_id'), nullable=False) 
    name = db.Column(db.String(ALERT_NAME_MAX_SIZE), nullable=False) 

    def __init__(self, user_id, name): 
     self.user_id = user_id 
     self.name = name 

Ich bin der Lage, einige Benutzer hinzufügen, zum Beispiel

a = User(16) 
b = User(17) 
db.session.add(a) 
db.session.add(b) 
db.session.commit() 

und einige Schlagzeilen:

c = Alert(16, 'test') 
d = Alert(17, 'name_test') 
db.session.add(c) 
db.session.add(d) 
db.session.commit() 

Ich habe zwei Probleme mit dem Fremdschlüssel: Zunächst einmal, wenn ich versuche, den user_id Alarm zu ändern, ich bin in der Lage es zu tun, auch wenn die user_id ist nicht in der Datenbank

alert = Alert.query.get(1) 
alert.user_id = 1222 # not in the database 
db.session.commit() 

und ich bin in der Lage eine Warnung vor einem user_id nicht in der erstellen Datenbank:

r = Alert(16223, 'test') 
db.session.add(r) 

Ich verstehe nicht, warum sie keine Beziehung Einschränkung ist. Thx,

+0

Sind ändern? – polku

+0

Ich benutze SQLAlchemy – WillB

+0

Ja, ich kann das sehen, aber was ist Ihre Datenbank? SQLite erzwingt standardmäßig keine Fremdschlüssel. Sie müssen eine bestimmte Konfiguration verwenden, um mit SQLAlchemy arbeiten zu können. – polku

Antwort

0

So finde ich, wie man es mit this stackoverflow question macht, finde ich, wie man Fremdschlüsseleinschränkung erzwingt. verwenden Sie SQLite

ich juste dies nichts zu models.py in __init__.py hinzufügen und

@event.listens_for(Engine, "connect") 
    def _set_sqlite_pragma(dbapi_connection, connection_record): 
     if isinstance(dbapi_connection, SQLite3Connection): 
       cursor = dbapi_connection.cursor() 
       cursor.execute("PRAGMA foreign_keys=ON;") 
       cursor.close() 
0

In Ihrem Code ist ein Fehler bei der Initialisierung der Alert-Klasse aufgetreten. Sie sollten die backref-Variable (die 'Benutzer' ist) anstelle der Benutzer-ID verwenden, während Sie Alert initialisieren. Der folgende Code sollte funktionieren.

class User(db.Model): 

    __tablename__ = "user" 
    __table_args__ = {'extend_existing': True} 
    user_id = db.Column(db.BigInteger, primary_key=True) 
    alerts = db.relationship('Alert', backref='user', lazy='dynamic') 

    def __init__(self, user_id): 
     self.user_id = user_id 


class Alert(db.Model): 

    __tablename__ = 'alert' 
    alert_id = db.Column(db.Integer, primary_key=True, autoincrement=True) 
    user_id = db.Column(db.BigInteger, db.ForeignKey('user.user_id'), nullable=False) 
    name = db.Column(db.String(ALERT_NAME_MAX_SIZE), nullable=False) 

    def __init__(self, user, name): 
     self.user = user 
     self.name = name 

Es funktioniert wie folgt:

>>> a = User(7) 
>>> db.session.add(a) 
>>> db.session.commit() 
>>> b = Alert(a, 'test') 
>>> db.session.add(b) 
>>> db.session.commit() 
>>> alert = Alert.query.get(1) 
>>> alert.user_id 
7 
>>> alert.user 
<app.User object at 0x1045cb910> 
>>> alert.user.user_id 
7 

Es ist nicht Sie Variable wie d = Alert(88, 'trdft')

zuweisen lässt ich glaube, Sie Flask SqlAlchemy's One-to-Many Relationships um weitere Informationen zu lesen.

+0

Funktioniert nicht, ich kann immer noch Alarm mit keine vorhandene user_id erstellen und ändern Sie eine Warnung mit einer nicht vorhandenen user_id – WillB

+0

Versuchen Sie die bearbeitete Antwort – Rohanil

+0

Hallo, Thx, aber es funktioniert immer noch nicht, ich kann 'd = Alert (88, 'trdft') erstellen, auch wenn 88 nicht in der Benutzer db – WillB

0

Wenn Sie SQLite verwenden, werden Fremdschlüsseleinschränkungen standardmäßig nicht erzwungen. Informationen hierzu finden Sie in der Dokumentation unter Enabling Foreign Key Support.