前因

最近在使用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. Sass Maps的函数-map-remove($map,$key)、keywords($args)

    map-remove($map,$key) map-remove($map,$key) 函数是用来删除当前 $map 中的某一个 $key,从而得到一个新的 map.其返回的值还是一个 map.他并不 ...

  2. shell脚本检索所有mysql数据库中没有primary key的表

    1.mkdir -p /root/scripts/ 2. cd /root/scripts/ vim query.sql,代码如下: SELECT CONCAT(t.table_schema,&quo ...

  3. spring boot与ElasticSearch的集成

    本文主要介绍Spring boot与ElasticSearch的集成,因为Spring boot的教程以及ElasticSearch的学习其他博客可能更优秀,所以建议再看这篇文章前先学习学习一下Spr ...

  4. bzoj4987 Tree 树上背包

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4987 题解 一道还不错的题咯. 很容易发现一个结论:这 \(k\) 个点构成的一定是一个连通块 ...

  5. 【学习笔记】圆方树(CF487E Tourists)

    终于学了圆方树啦~\(≧▽≦)/~ 感谢y_immortal学长的博客和帮助 把他的博客挂在这里~ 点我传送到巨佬的博客QwQ! 首先我们来介绍一下圆方树能干什么呢qwq 1.将图上问题简化到树上问题 ...

  6. 爬虫技术:scrapy 知识点一

    ---恢复内容开始--- 1.scrapy框架 每一步的解释: step1:引擎从爬虫器获取要爬行的初始请求. step2:引擎在调度程序中调度请求,引擎把这个初始请求传递给调度器,并向调度器索要下一 ...

  7. 6.jaxp的sax方式操作

    1.sax解析的原理 (1)解析xml有两种技术 dom 和 sax dom: 根据xml的层级结构在内存中分配一个树形结构,把xml中标签,属性,文本封装成对象 sax: 事件驱动,一行一行边读边解 ...

  8. Unparseable date: "Mon Aug 15 11:24:39 CST 2016",时间格式转换异常

    String datestr= "Mon Aug 15 11:24:39 CST 2016";//Date的默认格式显示 Date date=new SimpleDateForma ...

  9. Android USB驱动源码分析(-)

    Android USB驱动中,上层应用协议里最重要的一个文件是android/kernel/drivers/usb/gadget/android.c.这个文件实现USB的上层应用协议. 首先包含了一些 ...

  10. Vue的跨域设置

    1.在使用vue开发的时候经常要涉及到跨域的问题,其实在vue cli中是有我们设置跨域请求的文件的. 2.当跨域无法请求的时候我们可以修改工程下config文件夹下的index.js中的dev:{} ...