首页 > 解决方案 > sql alchemy 在提交后将外键字段设置为 None

问题描述

每个人。我发现 SQL alchemy 的行为非常奇怪。当我尝试插入新的设备实例时,在提交 sql alchemy 后将类型字段设置为无。这是我的模型:

class BaseTable(db.Model):
    __abstract__ = True

    id = db.Column(db.Integer, primary_key=True, unique=True,
                   index=True, autoincrement=True, nullable=False)

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.date_created = dt.datetime.utcnow()


class Device(BaseTable):
    __tablename__ = "device"

    node_id = db.Column(db.ForeignKey('node.id', ondelete='CASCADE'), index=True, nullable=False)
    name = db.Column(db.Unicode(255), nullable=False)
    description = db.Column(db.Unicode, nullable=True)
    type = db.Column(db.ForeignKey('device_type.id', ondelete='SET NULL'), index=True, nullable=True)
    type_description = db.relationship("DeviceType", lazy='joined')


class DeviceType(BaseTable):
    __tablename__ = "device_type"

    name = db.Column(db.Unicode(255), unique=True, index=True, nullable=False)
    code = db.Column(db.Unicode(255), unique=True, index=True, nullable=False)

在 device_type 表中有 6 个条目,id 为 1 到 6。我为创建新设备实例做了简单的发布请求。这是控制器的代码:

@accepts(schema=post_schema, api=api)
@responds(schema=main_schema, api=api)
def post(self):

    strer = ''
    result = None

    payload = api.payload

    try:
        entity = post_schema().load(payload)
        result = crud_service.post(entity, log, db_session.session)
    except Exception as ex:
        strer += str(ex)

    if result is None:
        return response500(log, strer)
    else:
        return result

在 crud_service.post 我有:

session.add(entity)
session.commit()
return entity

因此,当我在有效负载中发出发布请求时,我得到设备类型 = 5(例如)。我确定我的 device_type 表中有这个 ID。但是在 sql alchemy 之后session.commit(),设备类型为无。之后,如果我提出 put 请求并重写类型

ent = session.query(model)\
      .filter(model.id == dict_entity['id'])\
      .update(ent_dict)
session.commit()

我按预期输入了我的数据库。因此,似乎 sql alchemy 通过执行 session.add() 将我的设备的类型字段设置为 None,但 session.update() 不是。谁能解释这种行为?我的模型可能有问题吗?

标签: sqlalchemyflask-sqlalchemy

解决方案


看来我发现了问题。我删除 type_description = db.relationship("DeviceType", lazy='joined') 现在它工作正常。我会看到另一种建立关系领域的方法


推荐阅读