2017-12-06 7 views
0

데이터베이스에서 항목을 삭제할 때 (내가 구성하지 않은) 계단식 연쇄 삭제가 나타납니다. 삭제 된 항목에 해당하는 범주 항목이 삭제됩니다. 어떻게 이런 일이 일어나지 않게 할 수 있습니까? 여기Sqlalchemy Flask 응용 프로그램에서 예기치 않은 계단식 삭제

from sqlalchemy import Column, ForeignKey, Integer, String 
from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy.orm import relationship 
from sqlalchemy import create_engine 


Base = declarative_base() 


class User(Base): 
    """Object holding information about individual registered users""" 

    __tablename__ = 'user' 
    id = Column(Integer, primary_key=True) 
    name = Column(String(250), nullable=False) 
    email = Column(String(250), nullable=False) 
    picture = Column(String(250)) 


class Category(Base): 
    """Object holding information about item categories""" 

    __tablename__ = 'category' 
    id = Column(Integer, primary_key=True) 
    name = Column(String(250), nullable=False) 


class Item(Base): 
    """Object holding information about individual catalog items""" 

    __tablename__ = 'item' 
    id = Column(Integer, primary_key=True) 
    name = Column(String(250), nullable=False) 
    description = Column(String(5000), nullable=False) 
    category_id = Column(Integer, ForeignKey('category.id')) 
    category = relationship("Category") 
    user_id = Column(Integer, ForeignKey('user.id')) 
    user = relationship("User") 


engine = create_engine('postgresql+psycopg2://********:********' 
         + '/itemcatalog.db', echo=False) 
Base.metadata.create_all(engine) 

삭제 트리거 코드입니다 :

가 여기 내 데이터베이스 설정의

예상되는 동작은 삭제 될 자사의 "ID"로 지정된 경우에만 항목입니다
@app.route('/item/<int:item_id>/delete/', methods=['GET', 'POST']) 

def delete_item(item_id): 
    item = session.query(Item).filter_by(id=item_id).one() 

    if request.method == 'POST': 
     session.delete(item) 
     session.commit() 
     flash('Item Successfully Deleted') 
     return redirect(url_for('show_catalog')) 
    else: 
     return render_template('deleteitem.html', item=item, 
           username=login_session['username'], 
           picture=login_session['picture']) 

, 다른 테이블에는 변경 사항이 없기 때문입니다.

실제 결과는 항목을 삭제하기위한 것이고이 항목에 해당하는 카테고리 테이블의 항목도 삭제됩니다.

UPDATE :

내가 데려 갈거야 단계는 다음과 같습니다

  1. 는 (해당 항목

이 보여 로그 삭제 데이터베이스

  • 에 새 항목 만들기 및 삭제)를 따르십시오. 새 항목 삭제

    2017-12-06 19:32:16 UTC [5383-22] [email protected] LOG: statement: SELECT category.id AS category_id, category.name AS category_name 
        FROM category 
    2017-12-06 19:32:16 UTC [5383-23] [email protected] LOG: statement: INSERT INTO item (name, description, category_id, user_id) VALUES ('Coffee', 'tasty beverage', 3, 2) RETURNING item.id 
    2017-12-06 19:32:16 UTC [5383-24] [email protected] LOG: statement: COMMIT 
    2017-12-06 19:32:16 UTC [5383-25] [email protected] LOG: statement: BEGIN 
    2017-12-06 19:32:16 UTC [5383-26] [email protected] LOG: statement: SELECT category.id AS category_id, category.name AS category_name 
        FROM category ORDER BY category.name ASC 
    2017-12-06 19:32:16 UTC [5383-27] [email protected] LOG: statement: SELECT item.id AS item_id, item.name AS item_name, item.description AS item_description, item.category_id AS item_category_id, item.user_id AS item_user_id 
        FROM item ORDER BY item.name ASC 
    

    :

    새 항목 추가 나는 그것 내가 원하는 방식으로 행동하지 볼 수있는 로그에서

    2017-12-06 19:33:14 UTC [5383-30] [email protected] LOG: statement: SELECT item.id AS item_id, item.name AS item_name, item.description AS item_description, item.category_id AS item_category_id, item.user_id AS item_user_id 
        FROM item 
        WHERE item.id = 7 
    2017-12-06 19:33:14 UTC [5383-31] [email protected] LOG: statement: SELECT category.id AS category_id, category.name AS category_name 
        FROM category 
        WHERE category.id = 3 
    2017-12-06 19:33:14 UTC [5383-32] [email protected] LOG: statement: SELECT item.id AS item_id, item.name AS item_name, item.description AS item_description, item.category_id AS item_category_id, item.user_id AS item_user_id 
        FROM item 
        WHERE 3 = item.category_id 
    2017-12-06 19:33:14 UTC [5383-33] [email protected] LOG: statement: UPDATE item SET category_id=NULL WHERE item.id = 5 
    2017-12-06 19:33:14 UTC [5383-34] [email protected] LOG: statement: UPDATE item SET category_id=NULL WHERE item.id = 6 
    2017-12-06 19:33:14 UTC [5383-35] [email protected] LOG: statement: DELETE FROM item WHERE item.id = 7 
    2017-12-06 19:33:14 UTC [5383-36] [email protected] LOG: statement: DELETE FROM category WHERE category.id = 3 
    2017-12-06 19:33:14 UTC [5383-37] [email protected] LOG: statement: COMMIT 
    2017-12-06 19:33:14 UTC [5383-38] [email protected] LOG: statement: BEGIN 
    2017-12-06 19:33:14 UTC [5383-39] [email protected] LOG: statement: SELECT category.id AS category_id, category.name AS category_name 
        FROM category ORDER BY category.name ASC 
    2017-12-06 19:33:14 UTC [5383-40] [email protected] LOG: statement: SELECT item.id AS item_id, item.name AS item_name, item.description AS item_description, item.category_id AS item_category_id, item.user_id AS item_user_id 
        FROM item ORDER BY item.name ASC 
    

    을,하지만 난에있어 이 행동을 멈추기 위해 무엇을 바꾸어야 할 것인가?

  • +0

    대화 형 Python 세션에서이 문제를 재현 할 수있는 기회가 있습니까? (a) 정확히 어떤 코드가이 동작을 트리거하는지, (b) 어떤 sqlalchemy 로그가 어떤 Python 문과 일치하는지 확인할 수 있습니까? – larsks

    답변

    0

    답장을 보내 주셔서 감사 드리며 혼란 스럽습니다. 내 실수는 어리석은 짓이었습니다 ... 테스트 용으로 새로운 데이터베이스 설정 파일을 만들었고, 기본 app.py 파일에서 경로를 업데이트하는 것을 잊어 버렸습니다.

    0

    설명 된 동작을 재현 할 수 없습니다. 나는 model.py에 데이터베이스 설치를 넣고 실행하면 다음

    from model import engine, User, Category, Item 
    from sqlalchemy.orm import sessionmaker 
    Session = sessionmaker(bind=engine) 
    
    s = Session() 
    
    c = Category(id=1, name='Misc') 
    u = User(id=1, name='example', email='[email protected]') 
    
    s.add(c) 
    s.add(u) 
    s.commit() 
    
    i1 = Item(id=1, name='foo', description='foo desc', category=c, 
          user=u) 
    i2 = Item(id=2, name='bar', description='bar desc', category=c, 
          user=u) 
    
    s.add(i1) 
    s.add(i2) 
    s.commit() 
    

    을 그리고 이후에 항목 중 하나를 삭제합니다

    >>> item = s.query(Item).filter_by(id=2).one() 
    2017-12-06 12:11:34,608 INFO sqlalchemy.engine.base.Engine BEGIN (implicit) 
    2017-12-06 12:11:34,609 INFO sqlalchemy.engine.base.Engine SELECT item.id AS item_id, item.name AS item_name, item.description AS item_description, item.category_id AS item_category_id, item.user_id AS item_user_id 
    FROM item 
    WHERE item.id = %(id_1)s 
    2017-12-06 12:11:34,609 INFO sqlalchemy.engine.base.Engine {'id_1': 2} 
    >>> s.delete(item) 
    >>> s.commit() 
    2017-12-06 12:11:44,915 INFO sqlalchemy.engine.base.Engine DELETE FROM item WHERE item.id = %(id)s 
    2017-12-06 12:11:44,916 INFO sqlalchemy.engine.base.Engine {'id': 2} 
    2017-12-06 12:11:45,014 INFO sqlalchemy.engine.base.Engine COMMIT 
    

    당신은에 의해 실행되는 하나의 DELETE 문 만이 있음을 볼 수있다 우리가 참조 Category을 선택하면 PostgreSQL을, 그리고 여전히 존재 :

    >>> s.query(Category).get(1) 
    2017-12-06 12:12:58,968 INFO sqlalchemy.engine.base.Engine BEGIN (implicit) 
    2017-12-06 12:12:58,970 INFO sqlalchemy.engine.base.Engine SELECT category.id AS category_id, category.name AS category_name 
    FROM category 
    WHERE category.id = %(param_1)s 
    2017-12-06 12:12:58,971 INFO sqlalchemy.engine.base.Engine {'param_1': 1} 
    <model.Category object at 0x7f42dfab1550> 
    

    당신이 다른 행동을보고하는 경우, 수있는 당신은 문제를 재현 할 특정 순서의 단계로 질문을 업데이트 하시겠습니까?

    +0

    의견을 보내 주셔서 감사합니다. 자세한 정보를 제공하기 위해 게시물을 업데이트했습니다. – treecoder

    관련 문제