1

PostgreSQLのテーブルは次のようになります

             Table "public.categories"
   Column   |           Type           | Modifiers
------------+--------------------------+-----------
 uuid       | uuid                     | not null
 name       | character varying        | not null
 parent     | character varying        | not null
 created_on | timestamp with time zone | not null
Indexes:
    "categories_pkey" PRIMARY KEY, btree (uuid)
    "categories_name_parent_key" UNIQUE CONSTRAINT, btree (name, parent)
Referenced by:
    TABLE "transactions" CONSTRAINT "transactions_category_id_fkey" FOREIGN KEY (category_id) REFERENCES categories(uuid)

持っていunique(name, parent)ます。私のTest

  def setUp(self):
        db.create_all()

    def session_commit(self):
        # noinspection PyBroadException
        try:
            db.session.commit()
        except:
            db.session.rollback()
        finally:
            pass
   def test_insert_same_category_twice(self):
        """
         category, parent relationship is unique
        """
        db.session.add(Category('test_insert_same_category_twice', 'parent1'))
        self.session_commit()
        self.assertEquals(1, len(db.session.query(Category).all()))
        db.session.add(Category('test_insert_same_category_twice', 'parent1')) # should fail
        self.session_commit()

    def tearDown(self):
        db.session.close()
        for tbl in reversed(db.metadata.sorted_tables):
            db.engine.execute(tbl.delete())

nameデータベースに同じparent理由で新しいカテゴリを挿入しようとすると失敗するはずですUniqueConstraintが、そうではありません

また、最後の行(上記のコードでは省略)でアサートすると、テーブルにいくつのエントリがありますか

self.assertEquals(2, len(db.session.query(Category).all()))

失敗する

    self.assertEquals(2, len(db.session.query(Category).all()))
AssertionError: 2 != 1

つまり、既存のエントリを上書きしますか?

ここで何がうまくいかないのですか?

アップデート

@ sr2222の回答に従って、次の方法でバグを解決しました

def session_commit(self):
    # noinspection PyBroadException
    try:
        db.session.commit()
    except:
        db.session.rollback()
        raise # added error to propagate up
    finally:
        pass
4

1 に答える 1

1

関数には、DB コミットの周りにsession_commitキャッチオールブロックがあります。exceptロールバックが失敗しない限り、これは常に成功します。あなたのアサートに関しては、エラーを押しつぶしているため、コミットは静かに失敗しているため、見つかった単一の行は元の編集されていないエントリである必要があります。検証で例外状態を条件付きで処理したい場合は、単に破棄するのではなく、キャッチして適切に処理する必要があります。

于 2013-04-01T13:51:21.487 に答える