奇人凡人の雑記帳

趣味とか投資とか、twitterに書きにくいことをこちらに書きます。毎週金曜更新目標(現在多忙のため月1の投資成績がメインです)

pythonanywhereでzipファイルの作成と格納

h05torです。

 

福原遥さんが昨日新型コロナ感染からついに復帰という報告がありました。

無事に回復されて良かったです。

 

ーーーーーーーーーーーーーーーー以下本編ーーーーーーーーーーーーーーーーー

 

私が仕事で使うためだけに作成したwebアプリ(pythonanywhere使用)でzipファイルの作成+ダウンロードといった機能があると便利だと思いましたので、実際に追加してみました。

今後の応用などのための備忘録として記事に残しておこうと思いました。

 

一つの記事に全部書くと長くなりますので今回はzipファイルの作成とその中へのファイルの格納までといたします。(h05torが怠情なだけ)

 

なお、本記事では基本的にpythonanywhere環境での使用となっておりますので、ディレクトリの取り方が特殊かもしれません。(逆に私自身は本職ではないので標準的な配置が分からないかも)

一応、今回のファイルの配置は以下の図のようになっていまして、フレームワークはFlask、pythonは3.8を使用しております。

pythonanywhereの仕様上(Flaskの場合?)user階層(実際はアカウント名)がカレントディレクトリとなることに注意です。

mysite階層中にあるflask_app.pyがデフォルトでwebサイトの立ち上げのpythonファイルとなり、同階層にあるmodule1.pyが個別のプログラムのモジュールです。

今回の流れとしましてはmodule1.pyの中でsave_space階層中に保存されているcsvファイルをzipファイルの中に格納するということをします。

f:id:h05tor:20220212115311p:plain



おそらくpythonだとデフォルトでzipfileのライブラリがデフォルトで入っている?(入っていなかったら申し訳ございません。クラウドだとpythonanywhere、ローカルだとanacondaなので入ってました)と思いますので、まずzipfileをimportします

 

import zipfile
#zipファイルはcsvファイルと同じsave_space階層に保存しますが、
#毎回ルートディレクトリから記述するの面倒なので共通部分をfolderとしてまとめます。
folder = "./save_space/"

with zipfile.ZipFile( folder + "zipfile.zip","w") as z:
    z.write(folder + "csvfile1.csv")
    z.write(folder + "csvfile2.csv")

zipファイルの生成とその中へのファイルの格納は

with zipfile.ZipFile構文で行うことができ、第1引数にzipファイルの名前を指定します。

第2引数の'w'は書き込みモードで、ファイルが存在しなければ新規作成、存在していれば上書き(既存の内容は削除)で保存されます。

この構文の中で、z.write(zipに格納したいファイル名)でファイルを格納することができます。

処理が終わり、zipファイルが生成されると以下の図のような配置になります。

f:id:h05tor:20220212131626p:plain

赤で囲ったzipfile.zipが今回生成したzipファイルで、黄色で囲った部分がzipファイルの中身となります。図のようにsave_spaceのフォルダごと格納しているため、解凍時に煩わしさがあるかもしれません。

その場合、以下のようにz.writeの第2引数にファイル名をディレクトリ部分無しで直接指定すると、save_spaceフォルダ無しで直接zipファイルの中に格納することができます。

(説明しにくいけど、第1引数で格納したいファイルを指定し、第2引数で所謂「名前を付けて保存」みたいな感じだと思います)

folder = "./save_space/"

with zipfile.ZipFile( folder + "zipfile.zip","w") as z:
    z.write(folder + "csvfile1.csv","csvfile1.csv")
    z.write(folder + "csvfile2.csv","csvfile2.csv")

この場合は以下の配置になります。

f:id:h05tor:20220212132628p:plain

 

なお余談ですが今回はpythonanywhere + Flaskを前提としているためuser階層がカレントディレクトリであるため相対パスで上の階層に戻るということはありませんでしたが、仮にローカル環境など他の環境ではmodule1.pyが存在するmysite階層がカレントディレクトリになるため、格納したいcsvfileを指定する際、

z.write("../save_space/csvfile1.csv")となるかと思うのですが、実はここで上の階層に戻る相対パス「..」が入っていると、何故か生成されたzipファイルの中に何も入っていないという現象が起こります。

このような場合はz.write("../save_space/csvfile1.csv","csvfile1.csv")というように相対パスを含まない第2引数を指定すると解決することができます。

※実はpythonanywhereのバックアップを取ってローカルで動かそうとしたら起こった奴です。

 

 

次回は続編として生成したzipファイルのダウンロード編の予定です。