烧瓶外键约束

时间:2016-08-05 15:20:11

标签: python flask foreign-keys flask-sqlalchemy

我在Flask中遇到外键问题。 我的模型如下:

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

我可以添加一些用户,例如

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

和一些提醒:

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

外键有两个问题: 首先,当我尝试修改user_id警报时,即使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)

我不明白为什么他们没有关系约束。 谢谢,

3 个答案:

答案 0 :(得分:1)

所以我发现如何使用this stackoverflow question ,我找到了如何强制外键约束。

我在regexp {scl\[0\]} $string 中添加此内容,并且不对__init__.py

进行任何更改
models.py

答案 1 :(得分:0)

您的代码中存在错误,无法初始化Alert类。在初始化Alert时,您应该使用backref变量(即'user')而不是user_id。以下代码应该工作。

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

它的工作原理如下:

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

它不允许您分配像d = Alert(88, 'trdft')

这样的变量

我认为您应该阅读Flask SqlAlchemy's One-to-Many Relationships了解更多详情。

答案 2 :(得分:0)

如果您使用的是SQLite,则默认情况下不会强制执行外键约束。请参阅文档中的Enabling Foreign Key Support以了解如何启用此功能。