coo_start
@coo_start (Yama leo)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

Djangoでformからcsvファイルを受け取り、それをdfに変換したい。 お力をお貸しください。。。

解決したいこと

Djangoでformからcsvファイルを受け取り、複数のcsvパターンに対応して
それをdfに変換したい。

発生している問題・エラー


Djangoにて、formからrequestでcsvファイルを受け取り、
それをdfに変換して別のpythonファイルに渡そうとしています。

まずdfに変換できないcsvファイルが入ってきて
行き着いた指定がこれです。これでdfに変更することができました。  
df =  pd.read_csv(io.StringIO(file.read().decode('CP932')), delimiter=',')

ですが、別のファイルを入れるとエラーがでます。

その他のファイルはencodeやdecodeを指定しなくても以下で読み取ってくれます。
df = pd.read_csv(file)


どちらが来ても良いように以下のコードで試してみました。

同じ記述で対応してるcsvファイルなら一つずつで通るので

一つ目失敗しても二つ目で対応している記載で待ち構えておけば、と考え
try exceptで二段構えでdfに変換を試しましたが、

二段にすると二段目でもエラーになってしまいます。


つまり、ファイルが何らかの形に変わってるのだと思いました。

どなたか、お知恵をお貸しいただけませんでしょうか。
何卒よろしくお願いします。





例)
一段目
first error 'cp932' codec can't decode byte 0xef in position

二段目
second error No columns to parse from file

または、問題・エラーが起きている画像をここにドラッグアンドドロップ

該当するソースコード

views.py

    if request.method == 'POST' and request.FILES['csvfile']:
        form = UploadFileForm(request.POST, request.FILES)
        file = request.FILES['csvfile']
        myfile = request.FILES['csvfile']
        try:
            df =  pd.read_csv(io.StringIO(file.read().decode('CP932')), delimiter=',')
        except Exception as e:
            print(f"first error{e}")
        try:
            df = pd.read_csv(myfile)
        except Exception as e:
            print(f"second error {e}")
        checkfunc(df)

自分で試したこと。。


### 自分で試したこと
dfに入れるfile名を変えてそれぞれに違う変数として渡した。

utf-8やcp932などencode指定を変えた。

engine='python'などの引数を入れた。



filesystemstorageに格納してみた。
これもエラー続出し
結果呼び出し方、pd.read_csvの入れ方がわからなくて進まず質問させて頂きました。。。。
 form = UploadFileForm(request.POST, request.FILES)
 myfile = request.FILES['csvfile']
 fs = FileSystemStorage()
 filename = fs.save(myfie.name, myfile)
 uploaded_file_url = fs.url(filename)




0

2Answer

解決できました!!!
temporaryfileは読み込めませんのエラーが出てて
一回目はpathを取ってwith openで開いてそのままdfに
それができなかった時の処理で最初に格納したfileをdfに変換。
これで解決しました。

おそらく格納される場所が一緒だと、
二度目使うときにファイルが大きいため
一時的な保存を完璧な状態でできなかったんじゃないかと思います。
なのでwith openにfilepathを入れて読み取ってみました。

質問に答えてくれた
@Carteletさんありがとうございました。
勇気とやる気を頂きました。

精進して、僕も人の質問に答えれるようになります。

if request.method == 'POST':
    form = UploadFileForm(request.POST, request.FILES)
    file = request.FILES['csvfile']
    filepath = file.temporary_file_path()
    try:
        with open(filepath, "r", encoding="CP932") as f:
            df = pd.read_csv(f)
    except Exception as e:
        print(f"zero with error {e}")
        try:
            df = pd.read_csv(file)
        except Exception as e:
            print(f"first error {e}")
    checkfunc(df)
    state = "プログラムが完了しています"

一つ目をwith文を使って開けて保存することで、
temporaryfileを破壊せずに
二つ目も処理できた。

1Like

こうするとどうでしょうか?

views.py
    if request.method == 'POST' and request.FILES['csvfile']:
        form = UploadFileForm(request.POST, request.FILES)
        file = request.FILES['csvfile'].read()
        try:
            df =  pd.read_csv(io.StringIO(file.decode('CP932')), delimiter=',')
        except Exception as e:
            print(f"first error{e}")
        try:
            df = pd.read_csv(io.StringIO(file), delimiter=',')
        except Exception as e:
            print(f"second error {e}")
        checkfunc(df)
0Like

Comments

  1. @coo_start

    Questioner

    ご回答ありがとうございます。
    感謝致します。

    上記のコードで再度試してみましたが、
    first error'cp932' codec can't decode byte 0xef in position 1027633: illegal multibyte sequence,

    second initial_value must be str or None, not TemporaryUploadedFile,



    尚一段目に対応するcsvファイルをあげるとdf
    に変換することが出来ました。



    データベースに登録したりなど様々ことを試してみましたが、

    実力、知識不足で進めず。


    ですがご回答いただけたことで
    力になりました。

    ずっと1人で独学でやってきたので嬉しいです。
    ありがとうございます!

Your answer might help someone💌