2017-09-26 20 views
0

web2pyが新しくなりました。私は書類登録申請をしています。各文書には、登録年度に固有の番号が割り当てられます。私は、unique=Trueの制約を適用する計算された文字列フィールドを数値と年を組み合わせて使用​​しようとしています。web2py固有の制約が適用されていません

私はSQLiteの、web2pyのデフォルトのデータベースを使用しています。私のテーブル定義:

db.define_table('doc_master_new', 
      Field('sr_no', 'string', unique=True, notnull=True, 
        compute=lambda r: str(r['inward_no']) + '/' + str(r['inward_date'].year)), 
      Field('inward_no', 'integer'), 
      Field('inward_date', 'date', default=request.now), 
      Field('doc_date', 'date'), 
      Field('doc_type', db.doc_type, requires=IS_IN_DB(db, db.doc_type, '%(type_code)s', orderby=db.doc_type.id)), 
      Field('applicant_type'), ## creditor/borrower/third-party 
      Field('no_defect', 'boolean', default=False), 
      Field('time_stamp', 'datetime', default=request.now) 
      ) 

とコントローラ:

def add_doc():  
db.doc_master_new.sr_no.writable = False 
db.doc_master_new.sr_no.readable = False 
db.doc_master_new.time_stamp.writable = False 
db.doc_master_new.time_stamp.readable = False 
db.doc_master_new.no_defect.writable = False 
db.doc_master_new.no_defect.readable = False 
form = SQLFORM(db.doc_master_new, 
       labels = { 'inward_no':'SR No', 
         'inward_date':'SR Date', 
         'doc_date':'Document Date', 
         'doc_type':'Document Type', 
         } 
      ) 
if form.process().accepted: 
    session.flash = 'Document Added' 
    redirect(URL('index_n')) 
return locals() 

固有の制約が適用されていない、と同じ値がテーブルに挿入されています。なぜ私は理解できません。 SQLiteのドキュメントはNULL値が他のNULLを含む他のすべての値とは異なると考えられ、そのためnotnull制約を追加しましたが、それでも重複が許可されていると言います。

誰かが助けてくれますか?

答えて

0

unique=Trueを追加した可能性があります。のテーブルが最初に作成された後です。彼らはDALの移行を扱いますが、そのようなUNIQUENOT NULLなどの制約を変更することはありません - あなたは、テーブルが既に作成された後に、これらの制約を変更したい場合は、あなたが他のいくつかのツールを使用して、いくつかの操作を行う必要があります。

また、unique=Trueは、データベースのレベルではなく、フォーム入力で適用されていることに注意してください。つまり、ユーザーが制約に違反する値を送信すると、データベース・ドライバーは例外をスローし、ユーザーにはエラー・チケットが表示されます。代わりに、onvalidation callback.process()を介して、フォーム提出時に制約を実施することを検討してください。こうすることで、重複した組み合わせがデータベースに送られるのを防ぎ、フレンドリーなエラーメッセージをユーザーに報告することができます。

最後に、sr_noフィールドの唯一の目的が一意制約を強制することである場合は、代わりに複数列の一意性制約を設定することを検討してください(DALの外部で行う必要があります。そのような制約を定義する)。

+0

正直な@Anthonyは、後で 'unique'制約を追加しました。私は、データベースレベルの制約を使用しようとしたときにフォームレベルの検証コード ' db.doc_master_new.inward_no.requires = IS_NOT_IN_DB(DB(db.doc_master_new.inward_date.year == request.vars.inward_date.year)、「doc_master_new.inward_no 「

+0

year''それはちょうどだろう 『オブジェクトが属性を持っていない』) 'エラーチケット'タイプを 『>」た』 'request.vars.year'、ない' request.vars.inward_date.year' 。上記の回答が元の質問に答える場合は、それを正しく記入してください。 – Anthony

+0

'request.vars.year'は今年を返し、' inward_date.year'が異なっていてもエラーメッセージを投げました。 @Anthonyがアドバイスしたように、DALを使用する代わりに、以下のコードをフォーム/のOnValidation関数で使用しました。ありがとう@Anthony –

関連する問題