【问题标题】:SQLAlchemy delete association objectsSQLAlchemy 删除关联对象
【发布时间】:2013-11-13 05:15:11
【问题描述】:

我正在尝试通过过滤其中一个关系中的列来批量删除关联表中的对象。我在 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)

最后没有删除,SQLAlchemy查询是

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')

【问题讨论】:

  • 什么是 SQLAlchemy 版本? SQL 数据库和版本是什么?
  • SQLAlchemy 是 0.8.2,SQL 数据库是 MySQL 5.6.12
  • 我也有同样的问题——你还没有找到解决办法吗?
  • 不,对不起,我没有。我最终使用了非常低效的解决方案,即创建查询、遍历结果并一一删除。

标签: python sql sqlalchemy flask flask-sqlalchemy


【解决方案1】:

我在使用 MySQL 5.6 的 SQLALchemy 0.9 中遇到了同样的问题。它看起来像一个错误/限制。但是,一种更好的解决方法(与创建查询、循环遍历结果并逐个删除它们相比)是在两个后续查询中执行此任务:

    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')

它对我来说效果很好,它应该也可以解决你的问题。

【讨论】:

  • 谢谢。我会尽快尝试,如果它对我有用,请告诉您。
  • 最后我有机会尝试您的解决方案,并且效果很好。谢谢!
猜你喜欢
  • 1970-01-01
  • 2021-08-26
  • 2011-06-29
  • 1970-01-01
  • 2015-07-31
  • 2015-03-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多