2016-12-27 6 views
0

これは、ユーザーの実行したアクションの記録をpython csvで構築する機能です。グローバルからユーザー名を取得し、amountパラメータで指定された増分を、ユーザーの行と現在の日付と一致するcsvの特定の場所に実行します。Python CSVを更新するための安全な方法とは

要するに、この関数はリスト内のcsvを読み込み、リスト全体をcsvファイルに書き直す前にデータを変更します。

行の最初の項目はすべてユーザー名で、ヘッダーには日付が入ります。

Accs\Dates,12/25/2016,12/26/2016,12/27/2016 
user1,217,338,653 
user2,261,0,34 
user3,0,140,455 

しかし、時々、ヘッダーが2番目の行にプッシュダウンされ、クラッシュするとデータが完全に消去される理由がわかりません。

また、この機能を実行し、同じファイルに書き込む複数のスクリプトがあることを指摘する必要があります。

統計情報を各ユーザーに個別に、個別に書き込み、後で組み合わせることができると考えています。そのため、書き起こしの可能性が排除されます。私がここにあるものから改善し、ファイル上のすべてを読み書きすることができれば素晴らしいだろう。

私がここでやろうとしているフェイルセーフの方法はありますか?

# Search current user in first rows and updating the count on the column (today's date) 
# 'amount' will be added to the respective position 
def dailyStats(self, amount, code = None): 
    def initStats(): 
     # prepping table 
     with open(self.stats, 'r') as f: 
      reader = csv.reader(f) 
      for row in reader: 
       if row: 
        self.statsTable.append(row) 
        self.statsNames.append(row[0]) 

    def getIndex(list, match): 
     # get the index of the matched date or user 
     for i, j in enumerate(list): 
      if j == match: 
       return i 

    self.statsTable = [] 
    self.statsNames = [] 
    self.statsDates = None 

    initStats() 
    today = datetime.datetime.now().strftime('%m/%d/%Y') 
    user_index = None 
    today_index = None 

    # append header if the csv is empty 
    if len(self.statsTable) == 0: 
     self.statsTable.append([r'Accs\Dates']) 
     # rebuild updated table 
     initStats() 

    # add new user/date if not found in first row/column 
    self.statsDates = self.statsTable[0] 
    if getIndex(self.statsNames, self.username) is None: 
     self.statsTable.append([self.username]) 
    if getIndex(self.statsDates, today) is None: 
     self.statsDates.append(today) 

    # rebuild statsNames after table appended 
    self.statsNames = [] 
    for row in self.statsTable: 
     self.statsNames.append(row[0]) 

    # getting the index of user (row) and date (column) 
    user_index = getIndex(self.statsNames, self.username) 
    today_index = getIndex(self.statsDates, today) 

    # the row where user is matched, if there are previous dates than today which 
    # has no data, append 0 (e.g. user1,0,0,0,) until the column where today's date is match 
    if len(self.statsTable[user_index]) < today_index + 1: 
     for i in range(0,today_index + 1 - len(self.statsTable[user_index])): 
      self.statsTable[user_index].append(0) 

    # insert pv or tb code if found 
    if code is None: 
     self.statsTable[user_index][today_index] = amount + int(re.match(r'\b\d+?\b', str(self.statsTable[user_index][today_index])).group(0)) 
    else: 
     self.statsTable[user_index][today_index] = str(re.match(r'\b\d+?\b', str(self.statsTable[user_index][today_index])).group(0)) + ' - ' + code 

    # Writing final table 
    with open(self.stats, 'w', newline='') as f: 
     writer = csv.writer(f) 
     writer.writerows(self.statsTable) 

    # return the summation of the user's total count 
    total_follow = 0 
    for i in range(1, len(self.statsTable[user_index])): 
     total_follow += int(re.match(r'\b\d+?\b', str(self.statsTable[user_index][i])).group(0)) 

    return total_follow 
+0

詳細をあなたの問題とあなたが期待している出力を説明することができます。ごくわずかな情報で手助けすることは不可能です。また、MWEで問題を再現してみてください。 – jlandercy

+0

こんにちは@jlandercy私は多くの情報を提供したいと思いますが、エラーはありませんでした。私がcsvをチェックすると、1行目がプッシュダウンされ、新しいヘッダーが作成されるか、データが完全に消去されます(この1つはまれですが、数回起こっています)。また、同じファイルで複数のスクリプトが実行されていることを指摘する必要があります。私は独学ですので、私の語彙はある程度に制限されています、MWEとは何ですか? – Randize

+0

私たちはあなたが何をしようとしているのか分からず、コードとファイル構造だけを送信しますが、コードが何をすべきかについての記述はありません。 – jlandercy

答えて

1

David Zが述べているように、並行性が原因の可能性が高いです。 CSV形式は、データベースの格納、索引付け、並べ替えには適していないことを追加します。これは、プレーン/テキストとシーケンシャルであるためです。

RDBMSを使用してデータを保存および更新し、定期的に統計を処理することができます。 CSV形式は単なるインポート/エクスポート形式です。

Python offers a SQLite binding標準ライブラリで、SQLiteスキーマでCSVコンテンツをインポート/更新し、CSVとして結果をダンプするコネクタを構築すると、データベースサーバーのインストールに心配することなく、concurencyを処理しネイティブフォーマットを維持できますPythonで新しいパッケージをインストールすることです。

+0

はい私は、ここでデータベースの格納に関する同じ問題について考えていました。あなたのご意見ありがとうございます。 – Randize

1

はまた、私は多分、複数のスクリプトがこの機能を実行し、同じファイルへの書き込み、わからないことが問題を引き起こしている場合ことを指摘する必要があります。

これはまさにあなたの問題です。 2つのファイルが同時に同じファイルに書き込もうとしたときに、2つのソースからの出力はと簡単にが混在してしまい、ファイルが混乱することがあります。

この問題を解決する簡単な方法は、それぞれのプロセス(またはスレッド)ごとに独自のファイルに書き込んだ後、最後にすべてのファイルを結合する別々のコードを作成することです。それは私がおそらくやることです。

あなたがすることができないのは、さまざまなプロセス/スレッドにすべての情報をまとめてファイルに書き込む「アグリゲータプロセス」に情報を送信することです。キーはですのみアグリゲータがファイルに書き込みます。もちろん、これを行うには、プロセス間通信(IPC)のいくつかの方法を構築する必要があります。また、プロセスのやり方によっては難しい場合もあります。実際、単純なプログラムのためにIPCを実装する最良の方法の1つは、一時ファイルを使用することです。これは前の段落と全く同じことです。

+0

あなたの入力をありがとう、あなたなしでアグリゲータのようなものがあることは知らなかったでしょう。 – Randize

関連する問題