2017-12-30 93 views
1

Postgresqlがサポートしているテーブルの一意な制約がありますが、それはPostgreSQLが私の理解からサポートしているものですが、私の操作をどこから見つけることができないようですORMを使用するときにSQLAlchemyで行います(一般的には、この場合のみではありません)。私はbulk_update_mappings()関数を使用していますが、制約は__table_args__の下の2番目です。 SQLAlchemy Coreを使用するか、独自のSQL文を作成する必要がありますか? dbがあなたのセッションのインスタンスであることを考えるとSQLAlchemy ORM - 制約チェックの延期

class Question(Base): 
    QuestionType = enum.Enum('QuestionType', 'mcq') 
    __tablename__ = 'questions' 
    id = Column(Integer, primary_key=True) 
    type = Column(Enum(_QuestionType), nullable=False) 
    description = Column(String, nullable=False) 
    question_order = Column(Integer, nullable=False) 
    question_set_id = Column(Integer, ForeignKey('question_sets.id', ondelete='cascade'), nullable=False) 

    question_set = relationship('QuestionSet', back_populates='questions') 

    __table_args__ = (
     UniqueConstraint('question_set_id', 'description'), 
     UniqueConstraint('question_set_id', 'question_order', deferrable=True) 
    ) 
    __mapper_args__ = { 
     'polymorphic_identity': 'question', 
     'polymorphic_on': type, 
    } 

#from another class 
def reorder(self, new_order, db): 
    order = [{'id':i, 'question_order': index} for index, i in enumerate(new_order)] 
    db.bulk_update_mappings(Question, order) 
    db.commit() 
+1

ラン 'db.execute(「ALL DEFERRED制約を設定」)'先送りするために、一括操作の前に現在のトランザクションのすべての遅延可能制約:https://www.postgresql.org/docs/current/static/sql-set-constraints.html。一意の制約がその名前を知っている場合にのみ、その制約を延期することもできます。 –

+0

これは機能します。私は自分の制約に名前をつけ、 'db.execute( 'SET CONSTRAINTS unique_order DEFERRED;')' – nav

+0

を実行しました。関連はありますが、dupeはありません:https://stackoverflow.com/questions/32533592/how-to-set-constraints- deferred-in-sqlalchemy-core、https://stackoverflow.com/questions/14210453/how-to-set-constraints-deferred-in-sqlalchemy-expression-language –

答えて

1

現在のトランザクションdefer all deferrable constraintsするために、一括操作の前に

db.execute('SET CONSTRAINTS ALL DEFERRED') 

を実行します。 not all constraints are deferrableは、たとえそのように宣言されたとしても。あなたがその名前を知っていれば、このような unique_order として、唯一のユニーク制約を延期することを選ぶことができます:

def reorder(self, new_order, db): 
    order = [{'id':i, 'question_order': index} for index, i in enumerate(new_order)] 
    db.execute('SET CONSTRAINTS unique_order DEFERRED') 
    db.bulk_update_mappings(Question, order) 
    db.commit()