我试图通过过滤其中一个关系中的列来批量删除关联表中的对象.我在sqlAlchemy中使用以下调用来进行删除
db.session.query(UserPaper).join(Paper,(UserPaper.paper_id ==
Paper.id)).filter(UserPaper.user_id == user.id).filter(Paper.journal_id
== journal.id).delete()
并导致以下错误
OperationalError: (OperationalError) (1054,"Unknown column 'papers.journal_id'
in 'where clause'") 'DELETE FROM userpapers WHERE userpapers.user_id = %s AND
papers.journal_id = %s' (1L,1L)
SELECT userpapers.user_id AS userpapers_user_id,userpapers.paper_id AS
userpapers_paper_id,userpapers.created AS userpapers_created,userpapers.read_at AS userpapers_read_at,userpapers.score AS userpapers_score
FROM userpapers JOIN papers ON userpapers.paper_id = papers.id
WHERE userpapers.user_id = :user_id_1 AND papers.journal_id = :journal_id_1
哪个是对的.从错误中我可以看到,当我将delete()附加到查询时,sql语句的连接部分会丢失,数据库显然不知道如何查找papers.journal_id列.我不明白为什么会发生这种情况?
这是我的ORM对象的设置
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer,primary_key=True)
email = db.Column(db.String(255),unique=True)
papers = db.relationship("UserPaper",backref=db.backref('users'),lazy='dynamic')
class Paper(db.Model):
__tablename__ = 'papers'
id = db.Column(db.Integer,primary_key = True)
title = db.Column(db.String(1024))
journal_id = db.Column(db.Integer,db.ForeignKey('journals.id'))
class UserPaper(db.Model):
__tablename__ = 'userpapers'
user_id = db.Column(db.Integer,db.ForeignKey('users.id'),primary_key=True)
paper_id = db.Column(db.Integer,db.ForeignKey('papers.id'),primary_key=True)
paper = db.relationship("Paper",backref=db.backref('user_paper'))
read_at = db.Column(db.DateTime)
score = db.Column(db.Integer)
class Journal(db.Model):
__tablename__ = 'journals'
id = db.Column(db.Integer,primary_key = True)
title = db.Column(db.String(100),index = True,unique = True)
papers = db.relationship('Paper',backref = 'journal',lazy = 'dynamic')
最佳答案
我使用MysqL 5.6与sqlALchemy 0.9有同样的问题.它看起来像一个bug /限制.但是,获得arround的一种更好的方法(与创建查询相比,循环结果并逐个删除它们)是在后续两个查询中执行此任务:
paperQuery = db.session.query(Paper.id)\
filter(Paper.journal_id == journal.id)
baseQuery = db.session.query(UserPaper)\
.filter(UserPaper.paper_id.in_(paperQuery.subquery()))
.filter(UserPaper.user_id == user.id).delete(synchronize_session='fetch')