sqlalchemy onetomany ORM升级版

2024-10-02 14:28:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个表:Eca_users和Eca_user_emails,一个用户可以有多个电子邮件。我收到用户和他们的电子邮件json。我不会把它们加载到mssql数据库中。用户可以更新他们的电子邮件,所以在这个json中,我可以让相同的用户使用新的(或更改的)电子邮件。 我的代码

# some import here
Base = declarative_base()

class Eca_users(Base):
    __tablename__ = 'eca_users'
    sql_id = sqlalchemy.Column(sqlalchemy.Integer(), primary_key = True)
    first_id = sqlalchemy.Column(sqlalchemy.String(15))
    name = sqlalchemy.Column(sqlalchemy.String(200))
    main_email = sqlalchemy.Column(sqlalchemy.String(200))
    user_emails = relationship("Eca_user_emails", backref=backref('eca_users'))

class Eca_user_emails(Base):
    __tablename__ = 'user_emails'
    sql_id = sqlalchemy.Column(sqlalchemy.Integer(), primary_key = True)
    email_address = Column(String(200), nullable=False)
    status = Column(String(10), nullable=False)
    active = Column(DateTime, nullable=True)
    sql_user_id = Column(Integer, ForeignKey('eca_users.sql_id'))

def main()
    engine = sqlalchemy.create_engine('mssql+pymssql://user:pass/ECAusers?charset=utf8')
    Session = sessionmaker()
    Session.configure(bind = engine)
    session = Session()

    #then I get my json, parse it and...
    query = session.query(Eca_users).filter(Eca_users.first_id == str(user_id))
    if query.count() == 0:
        # not interesting now
    else:
        for exstUser in query:
            exstUser.name = name  #update user info
            exstUser.user_emails = [:] # empty old emails
            # creating new Email obj
            newEmail = Eca_user_emails(email_address = email_record['email'],
                                       status = email_record['status'],
                                       active = active_date)
            exstUser.user_emails.append(newEmail) # and I get error here because autoflush


    session.commit()


if __name__ == '__main__':
    main()

错误消息: sqlalchemy.exc.IntegrityError: ... [SQL:'UPDATE user_emails SET SQL_user_id=%(SQL_user_id)s WHERE user_电子邮件.sql_id=%(user_emails_sql_id)s'][参数:{'sql_user_id':无,'用户电子邮件_sql_id':十进制('1')}]

找不到任何关于此sql\u user\u id为None的原因:(

当我在调试器中检查exstUser和newEmail对象时,看起来一切正常。我是说所有的参考资料都没问题。session obj和它的dirty属性在调试器中看起来也正常(为Eca_user_emails obj设置了sql_user_id)。在

对我来说最奇怪的是,这段代码在没有main函数的情况下工作得非常好,只是类声明之后的所有代码。但在我写了主声明并把所有代码都放在这里之后,我开始得到这个错误。 我对Python完全陌生,所以这可能是一个愚蠢的错误。。。 有什么办法解决吗?原因是什么?感谢您阅读本文:)

顺便说一下:Python3.4,sqlalchemy 1.0,SQL Server 2012


Tags: 代码用户idsqlstringsqlalchemymain电子邮件
1条回答
网友
1楼 · 发布于 2024-10-02 14:28:59

sql_user_idNone,因为默认情况下,当您删除关系中的子对象时,SQLAlchemy会清除外键,也就是说,当您清除exstUser.user_emails时,SQLAlchemy将所有这些实例的sql_user_id设置为None。如果希望SQLAlchemy在从Eca_users分离时为Eca_user_emails实例发出DELETEs,则需要将delete-orphancascade选项添加到user_emails关系中。如果你想添加一个

user_emails = relationship("Eca_user_emails", backref=backref('eca_users'), cascade="save-update, merge, delete, delete-orphan")

您可以在SQLAlchemy docs中找到有关级联的更多信息

相关问题 更多 >