2016-08-05 1 views
0

플라스크의 외래 키에 문제가 있습니다.플라스크 외래 키 제한

Model.py 내가 예를

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

를 들어, 일부 사용자를 추가 할 수 있어요

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 

일부 경고 : 내 모델은 다음과 같다

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

외래 키와 관련된 두 가지 문제가 있습니다 :나는 USER_ID 경고를 수정하려고 할 때 모든 6,첫째, 나는 USER_ID 데이터베이스

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

에없는 경우에도 그것을 할 수 있어요 그리고 난에 아닌 USER_ID와 경고를 만들 수 있어요 데이터베이스 :

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

왜 나는 관계 제한이 없는지 이해할 수 없습니다. Thx,

+0

에 아무 것도 변경하지 juste? – polku

+0

SQLAlchemy를 사용 중입니다 – WillB

+0

그래도 알 수 있겠지만 데이터베이스는 무엇입니까? SQLite는 외래 키를 기본적으로 적용하지 않으므로 SQLAlchemy에서 작동하도록 특정 구성을 사용해야합니다. – polku

답변

0

그래서 나는 this stackoverflow question으로 어떻게 할 수 있는지 찾아 내고, 외래 키 제약을 강제하는 방법을 찾았습니다.

나는 __init__.py이를 추가하고 SQLite는 사용하고 models.py

@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

Alert 클래스의 초기화에 실수가 있습니다. Alert를 초기화하는 동안 user_id 대신 backref 변수 ('user')를 사용해야합니다. 다음 코드가 작동해야합니다.

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 

그것은 다음과 같이 작동합니다 : 그것은 당신이 d = Alert(88, 'trdft')

같은 변수를 할당 할 수 없습니다

>>> 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 

난 당신이 자세한 내용은 Flask SqlAlchemy's One-to-Many Relationships를 읽어한다고 생각합니다.

+0

작동하지 않습니다. 여전히 존재하지 않는 user_id로 경고를 생성 할 수 있습니다. 그리고 존재하지 않는 user_id를 가진 alerte 수정하기 – WillB

+0

편집 된 답변 시도 – Rohanil

+0

안녕하세요, Thx하지만 여전히 작동하지 않습니다. 88이 (가) 없더라도'd = Alert (88, 'trdft') '를 만들 수 있습니다. 사용자 db – WillB

0

SQLite를 사용하는 경우 외래 키 제약 조건은 기본적으로 적용되지 않습니다. 이 기능을 활성화하는 방법은 설명서의 Enabling Foreign Key Support을 참조하십시오.