前因

最近在使用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 \nFROM 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即可

最新文章

  1. ASP.NET Core的配置(1):读取配置信息
  2. mysql环境搭建
  3. Linux rpm 命令参数使用详解[介绍和应用]
  4. Squid服务日志分析
  5. SQL Server 2005 中的同义词
  6. 常用gradle命令
  7. [翻译][MVC 5 + EF 6] 10:处理并发
  8. poj3624背包问题(一维数组)
  9. python的bind函数
  10. Quartz框架的使用
  11. x0vncserver Fatal server error: no screens found
  12. mybatis 一点整理
  13. freemarker中的list 前端模板
  14. web前端性能调优(二)
  15. Iterator invalidation(迭代器失效)
  16. 学习笔记TF035:实现基于LSTM语言模型
  17. mysql 联合表(federated)及视图
  18. flask form表单验证
  19. 浏览器数据库 IndexedDB 入门
  20. Hadoop "Cannot create directory .Name node is in safe mode."解决方案

热门文章

  1. 如何去除inline-block的默认间距
  2. MySQL MHA+Keepalived
  3. MySQL MHA之 master_ip_failover.sh脚本
  4. 快速失败(fail—fast)和 安全失败(fail—safe)
  5. python 图像处理中二值化方法归纳总结
  6. MySQL添加主键、索引
  7. Debian取消从光盘安装软件的方式(please insert the disc labeled)
  8. c#蜘蛛
  9. vue项目打包之后原本好的样式变得不好了的原因分析
  10. pytest_用例运行级别_函数级