Python(英文のデータベース化006: 単語テーブル内の文IDの更新)

■単語のレコードに対して文のIDを追加する。
前回は、文や単語をそれぞれのデータベースのテーブルに新規に追加するだけだったけど、同じ単語がくる場合、新しく単語を追加するのではなく、既存の単語に対して文のIDのみを追加するようにしたい。

操作を考えると以下のようになる。
1.既存の単語テーブルに含まれているか?(SELECT文でデータ確認)
2.含まれない場合は、新規追加
3.含まれる場合は、該当する単語のレコードの文のIDで空いているところを更新

ちなみに、文と単語のテーブルは下のような感じ。
・ 文テーブル(文のID、文のカテゴリー、文本体、備考)
・ 単語テーブル(単語のID、単語本体、文のID001、文のID001での意味、文のID002、文のID002での意味、文のID003、文のID003での意味、(途中省略)、 文のID020、文のID020での意味、備考)
ここで、単語テーブルの「文のIDxxx」の中でまだ埋まっていない所に記入していきたい。

下の例文で見てみると、informationなどが両方の文に入っている。そのため、上の文IDを001、下を002とすれば、informationの単語テーブルに両方が入ることを期待してる。

This International Standard has been prepared to provide requirements for establishing, implementing, maintaining and continually improving an information security management system.
The adoption of an information security management system is a strategic decision for an organization.

では、さっそくコードを考えていく。
既存のテーブルに含まれるかは、次のようなコードとした。

        registeredword_num_cursor = cursor.execute('SELECT count(Word) FROM words where word = ' + '\'' + str(word) + '\'')
        registeredword_num = registeredword_num_cursor.fetchall()

期待する単語がすでにテーブルに入っている場合、SELECT文のCOUNTで数を確認すれば1以上になる。
cursor.executeの返り値が何なのかよくわからなかったけど、調べてみるとfetchallメソッドでリストとして取得できるよう。さらに、その中はタプル(tuple)としてデータが入っていた。タプルは、値の変更ができないリストのようなものという認識。デバッグでregisteredword_numを見てみると、listとtupleになっている。

その後は、if文で、1以上なら既存の単語の更新、それ以外は単語の新規追加とする。

更新部分のコードは下の通り。
「文のIDxxx」は 001 から 020 までにしているので、001 から順に空欄となっているか調べ、空欄だったらfor文をbreakで止め、そこに更新(UPDATE)をかける。

       for index in range(1, 21):
                index_str = "{:0=3}".format(index)
                sql = 'SELECT ' + 'sID' + index_str + ' FROM words where word = ' + '\'' + str(word) + '\''
                IDcontents_check_cursor = cursor.execute(sql)
                IDcontents = IDcontents_check_cursor.fetchall()
                if IDcontents[0][0] == "":
                    print(index)
                    break
            cursor.execute(
            'UPDATE words SET sID' + index_str + ' = ' + sID + ' where word = ' + '\'' + str(word) + '\'')
            connect.commit()
     

上の例文を1回実行すると、wordsテーブルは下のようになる。

informationは、1つ目の文と2つ目の文の両方に入っているため、1,2と文のIDが追加される。さらに、もう1回実行すると、下のように3,4とIDが追加される。全く同じ文を除くとか細かい処理は必要だけど、新しく単語が追加されることもなく既存の単語に対して更新ができた。

SQL単独では難しそうな制御も、Pythonの中でSQLを組み立て実行させるといったことをやれば、いろいろとできそう。