前因

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

flask开发问题小记的更多相关文章

  1. Windows使用virtualenv搭建flask开发环境

    virtualenv: VirtualEnv用于在一台机器上创建多个独立的Python虚拟运行环境,多个Python环境相互独立,互不影响,它能够: 在没有权限的情况下安装新套件 不同应用可以使用不同 ...

  2. flask开发restful api系列(8)-再谈项目结构

    上一章,我们讲到,怎么用蓝图建造一个好的项目,今天我们继续深入.上一章中,我们所有的接口都写在view.py中,如果几十个,还稍微好管理一点,假如上百个,上千个,怎么找?所有接口堆在一起就显得杂乱无章 ...

  3. flask开发restful api

    flask开发restful api 如果有几个原因可以让你爱上flask这个极其灵活的库,我想蓝图绝对应该算上一个,部署蓝图以后,你会发现整个程序结构非常清晰,模块之间相互不影响.蓝图对restfu ...

  4. 使用flask开发网站后端

    Flask 是一个用于 Python 的微型网络开发框架,可以用于快速的搭建一个小型的网站. 我的搜索引擎:http://www.abelkhan.com 就是基于flask开发 一个flask的He ...

  5. Flask开发遇到的问题:BuildError: Could not build url for endpoint 'main.followers' with values ['username']. Did you mean 'main.user' instead?

    @(Flask Web Development 12th chapter) 描述 Flask开发中遇到BuildError: Could not build url for endpoint 'mai ...

  6. 在 Django/Flask 开发服务器上使用 HTTPS

    使用 Django 或 Flask 这种框架开发 web app 的时候一般都会用内建服务器开发和调试程序,等程序完成后再移交到生产环境部署.问题是这些内建服务器通常都不支持 HTTPS,我们想在开发 ...

  7. 用flask开发个人博客(4)—— flask中4种全局变量

    https://blog.csdn.net/hyman_c/article/details/53512109 一  current_app current_app代表当前的flask程序实例,使用时需 ...

  8. Flask开发系列之初体验

    Flask开发初探 介绍 在日常开发中,如果需要开发一个小型应用或者Web接口,一般我是极力推崇Flask的,主要是因为其简洁.扩展性高. 从这篇文章开始,我会写一个关于Flask的系列文章,通过多个 ...

  9. 【selenium+python】之Python Flask 开发环境搭建(Windows)

    一.先安装python以及pip 二.其次, Python的虚拟环境安装: 在github上下载https://github.com/pypa/virtualenv/tree/master  zip文 ...

随机推荐

  1. Calendar日历

    Calendar calendar=Calendar.getInstance(); //上一年的今天 calendar.add(Calendar.YEAR,-1); System.out.printl ...

  2. bzoj5161 最长上升子序列 状压DP(DP 套 DP) + 打表

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=5161 题解 回顾一下以前用二分求 LIS 的方法:令 \(f[i]\) 表示长度为 \(i\) ...

  3. python已处理的异常

    字符串比较中,如果一个字符串有内容,另一个没有内容,python不会报错,而是认为两个字符串不相同如 a=" b="" if a[4:5]==b[4:5]: print( ...

  4. C#-弄懂泛型和协变、逆变

    脑图概览 泛型声明和使用 协变和逆变 <C#权威指南>上在委托篇中这样定义: 协变:委托方法的返回值类型直接或者间接地继承自委托前面的返回值类型; 逆变:委托签名中的参数类型继承自委托方法 ...

  5. java生成快递单并调用打印机打印

    生成快递单过程中需要生成条形码,生成条形码可参考:https://www.cnblogs.com/linbky/p/12091248.html 下面这段代码生成的快递单是完全符合京东快递的10 x 1 ...

  6. SQL笔试

    一.题目 二.练习数据 SELECT VERSION(); create table CDM_AGENT(ano VARCHAR(6),aname VARCHAR(8)); create table ...

  7. click和blur冲突的问题

    昨天在前端群里讨论到一个问题,大家平时做表单验证的时候一般都有个input框和删除按钮,然后习惯性在失去焦点的时候去验证输入的内容是否正确,做验证,发请求等等.这个时候,那个点击删除按钮往往也就触发了 ...

  8. Flutter 中的基本路由

    Flutter 中的路由通俗的讲就是页面跳转.在 Flutter 中通过 Navigator 组件管理路由导航,并提供了管理堆栈的方法.如:Navigator.push 和 Navigator.pop ...

  9. BZOJ 4484: [Jsoi2015]最小表示(拓扑排序+bitset)

    传送门 解题思路 \(bitset\)维护连通性,给每个点开个\(bitset\),第\(i\)位为\(1\)则表示与第\(i\)位联通.算答案时显然要枚举每条边,而枚举边的顺序需要贪心,一个点先到达 ...

  10. window 安装VisualSvn Server

    VisualSvn Server 1 .VisualSvn Server  介绍和下载 VisualSvn Server是免费的,而VisualSvn是收费的.VisualSvn是Svn的客户端,和V ...