rob*_*123 7 postgresql sqlalchemy flask python-2.7 flask-sqlalchemy
我正在尝试从 sql-alchemy 中的多对多关系中删除一个子对象。
我不断收到以下错误:
StaleDataError: DELETE statement on table 'headings_locations' expected to delete 1 row(s); Only 2 were matched.
Run Code Online (Sandbox Code Playgroud)
我查看了一些现有的堆栈交换问题(SQLAlchemy DELETE 错误由具有相同关系的延迟加载和动态版本引起,SQLAlchemy StaleDataError 在删除通过 ORM 插入的项目时发生 sqlalchemy.orm.exc.StaleDataError,SQLAlchemy Attempting两次删除多对多次要关系,从 MySQL 中的多对多关系删除) 以及阅读文档,但无法弄清楚为什么它不起作用。
我定义关系的代码如下:
headings_locations = db.Table('headings_locations',
db.Column('id', db.Integer, primary_key=True),
db.Column('location_id', db.Integer(), db.ForeignKey('location.id')),
db.Column('headings_id', db.Integer(), db.ForeignKey('headings.id')))
class Headings(db.Model):
__tablename__ = "headings"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80))
version = db.Column(db.Integer, default=1)
special = db.Column(db.Boolean(), default=False)
content = db.relationship('Content', backref=db.backref('heading'), cascade="all, delete-orphan")
created_date = db.Column(db.Date, default=datetime.datetime.utcnow())
modified_date = db.Column(db.Date, default=datetime.datetime.utcnow(), onupdate=datetime.datetime.utcnow())
def __init__(self, name):
self.name = name
class Location(db.Model):
__tablename__ = "location"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), unique=True)
account_id = db.Column(db.Integer, db.ForeignKey('account.id'))
version = db.Column(db.Integer, default=1)
created_date = db.Column(db.Date, default=datetime.datetime.utcnow())
modified_date = db.Column(db.Date, default=datetime.datetime.utcnow())
location_prefix = db.Column(db.Integer)
numbers = db.relationship('Numbers', backref=db.backref('location'), cascade="all, delete-orphan")
headings = db.relationship('Headings', secondary=headings_locations,
backref=db.backref('locations', lazy='dynamic', cascade="all"))
def __init__(self, name):
self.name = name
Run Code Online (Sandbox Code Playgroud)
我的删除代码如下:
@content_blueprint.route('/delete_content/<int:location_id>/<int:heading_id>')
@login_required
def delete_content(location_id, heading_id):
import pdb
pdb.set_trace()
location = db.session.query(Location).filter_by(id = location_id).first()
heading = db.session.query(Headings).filter_by(id = heading_id).first()
location.headings.remove(heading)
#db.session.delete(heading)
db.session.commit()
flash('Data Updated, thank-you')
return redirect(url_for('content.add_heading', location_id=location_id))
Run Code Online (Sandbox Code Playgroud)
无论我尝试以哪种方式删除子对象(db.session.delete(heading) 或 location.headings.remove(heading) 我仍然遇到相同的错误。
任何帮助深表感谢。
我的数据库是 postgresql。
编辑:我添加关系的代码:
new_heading = Headings(form.new_heading.data)
db.session.add(new_heading)
location.headings.append(new_heading)
db.session.commit()
Run Code Online (Sandbox Code Playgroud)
我会假设错误消息是正确的:确实在您的数据库中,您有 2 行链接Location
和Heading
实例。在这种情况下,您应该首先找出发生这种情况的地点和原因,并防止这种情况再次发生
首先,为了确认这个假设,您可以对您的数据库运行以下查询:
q = session.query(
headings_locations.c.location_id,
headings_locations.c.heading_id,
sa.func.count().label("# connections"),
).group_by(
headings_locations.c.location_id,
headings_locations.c.heading_id,
).having(
sa.func.count() > 1
)
Run Code Online (Sandbox Code Playgroud)假设,假设得到确认,通过手动删除数据库中的所有重复项(每个只留下一个)来修复它。
之后,将UniqueConstraint添加到您的headings_locations
表中:
headings_locations = db.Table('headings_locations',
db.Column('id', db.Integer, primary_key=True),
db.Column('location_id', db.Integer(), db.ForeignKey('location.id')),
db.Column('headings_id', db.Integer(), db.ForeignKey('headings.id')),
db.UniqueConstraint('location_id', 'headings_id', name='UC_location_id_headings_id'),
)
Run Code Online (Sandbox Code Playgroud)请注意,您需要将其添加到数据库中,仅将其添加到sqlalchemy
模型中是不够的。
现在,错误插入重复项的代码将因唯一约束违反异常而失败,您可以解决问题的根源。
归档时间: |
|
查看次数: |
2876 次 |
最近记录: |