• flask开发问题小记


    前因

    最近在使用flask开发一个APP的后端时出现了一些小问题。我使用sqlalchemy建立了如下多对多关系:

    中间表

    user_manager_group = db.Table('manage_group',
            db.Column('user_id', db.Integer,
                db.ForeignKey('users.id')),
            db.Column('group_id', db.Integer,
                db.ForeignKey('groups.id'))
            )
    
    

    小组

    class Group(db.Model):
        __tablename__ = 'groups'
        id = db.Column(db.Integer, primary_key=True)
        managers = db.relationship(
            'User',
            secondary=user_manager_group,
            backref=db.backref('manage_groups', lazy='joined'),
            lazy='dynamic')
    

    用户

    class User(db.Model):
        __tablename__ = 'users'
        id = db.Column(db.Integer, primary_key=True)
    

    App中用户与群组形成了一个多对多关系,一个用户可能是多个组的管理员,一个组也可能有多个管理员,在Android向我的接口发送删除时,出现了一个Bug

    sqlalchemy.orm.exc.StaleDataError: DELETE statement on table 'manage_group' expected to delete 1 row(s); Only 2 were matched. 
    

    无法删除某个小组

    排查

    在查找了许多资料后,终于发现了bug所在

    manage_group是user和group的中间表,

    CREATE TABLE user_manager (
            user_id INTEGER,
            grouo_id INTEGER,
            FOREIGN KEY(user_id) REFERENCES users (id),
            FOREIGN KEY(group_id) REFERENCES groups (id)
    );
    

    在Android端向我发送数据设定某个管理员时,我没有对数据进行验证,导致重复添加某一用户为某组的管理员。

    当(user_id,task_id)这个二元组重复时,sqlalchemy是无法删除group。

    修复

    首先我给后端加上了判断,一旦用户已经是某组的管理员,则不添加,但是这还不够,

    (user_id,group_id)这个二元组应当是唯一的,因此我们应当给它添加unique约束

    代码如下

     user_manager_group = db.Table('manage_group',                                                 
             db.Column('user_id', db.Integer,                                                      
                db.ForeignKey('users.id')),                                                       
             db.Column('group_id', db.Integer,                                                     
               db.ForeignKey('groups.id')),                                                      :
             db.UniqueConstraint("user_id","group_id",name="managegroup")                          
           )  
    

    但是使用flask-migrate迁移时出现了问题

    sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) UNIQUE constraint failed: _alembic_tmp_use
    r_task.user_id, _alembic_tmp_user_task.task_id [SQL: 'INSERT INTO _alembic_tmp_user_task (user_id,
     task_id) SELECT user_task.user_id, user_task.task_id 
    FROM user_task'] 
    

    此时我们需要打开migrate下的env文件往其中添加如下配置

    render_as_batch=True,
    

    添加后应为

        context.configure(connection=connection,
                          render_as_batch=True,
                          target_metadata=target_metadata,
                          process_revision_directives=process_revision_directives,
                          **current_app.extensions['migrate'].configure_args)
    

    此时执行flask db migrate即可

  • 相关阅读:
    逼哥
    作业
    malloc的底层实现
    docker基本使用
    对mudo中noncopyable类的理解
    整理
    替换war包中的文件
    SpringMVC(1):SpringMVC入门
    MySQL(5):安装MySQL
    MySQL(4):卸载MySQL
  • 原文地址:https://www.cnblogs.com/lynsyklate/p/7861203.html
Copyright © 2020-2023  润新知