添付ファイルの一括アップロード

ファイルを一括でアップロードしたいです。

簡単!ファイル一括アップロード(pykintone利用)を参考に試していますが、

どうしてもエラーが出てしまいます。原因がわかる方、教えていただけますでしょうか。

エラーの内容は

yaml.constructor.ConstructorError: while constructing a mapping
found unhashable key
in “account.yml”, line 9, column 3

です。

YAMLファイルの中身は殆ど伏字ですが下記の通りです。

domain: {XXX}
login:
id: {XXX}
password: {XXX}
basic:
id: {XXX}
password: {XXX}
apps:
{XXX}:
id: {XXX}
token: {XXX}

初心者様

お世話になっております.
トヨクモの江田と申します.

YAMLファイルの波括弧は不要です.
わかりづらい表現で申し訳ございません.

domain: XXX
login:
id: XXX
password: XXX
basic:
id: XXX
password: XXX
apps:
XXX:
id: XXX
token: XXX

江田篤史様

いつもお世話になっております。

ご教示ありがとうございます。

波括弧を削除したら上記のエラーは解消できました。

しかし、また別のエラーが発生してしまいました。

setattr(self, cell_key.rstrip(‘_filepath’), [sf.File.upload(filepath, app) for filepath in cell_val.split(‘;’)])
AttributeError: ‘NoneType’ object has no attribute ‘split’

簡単!ファイル一括アップロード(pykintone利用)の例をそのまま使用しております。

 

これはどういったエラーなのでしょうか

連投申し訳ございません。

Tracebackを全文転記します。

何卒、ご教示お願い致します。

 

Traceback (most recent call last):
File “C:\Users\XXXX\Desktop\新しいフォルダー\post.py”, line 19, in <module>
records = [Record(app, row) for row in data]
File “C:\Users\XXXX\Desktop\新しいフォルダー\post.py”, line 19, in <listcomp>
records = [Record(app, row) for row in data]
File “C:\Users\XXXX\Desktop\新しいフォルダー\post.py”, line 12, in __init__
setattr(self, cell_key.rstrip(‘_filepath’), [sf.File.upload(filepath, app) for filepath in cell_val.split(‘;’)])
AttributeError: ‘NoneType’ object has no attribute ‘split’

初心者様

お世話になっております.

CSVのセルが読み込めていないようですね.

一度下記コードで出力結果をご確認いただけますか?

・post.py

import pykintone
from pykintone import model
import pykintone.structure_field as sf
import codecs
import csv

class Record(model.kintoneModel):
  def __init__ (self, app, row):
    super(Record, self). __init__ ()
    for cell_key, cell_val in row.items():
      if '_filepath' in cell_key:
        setattr(self, cell_key.rstrip('_filepath'), [sf.File.upload(filepath, app) for filepath in cell_val.split(';')])
      else:
        setattr(self, cell_key, cell_val)

app = pykintone.load('account.yml').app()
with codecs.open('data.csv', 'r', 'utf-8') as csvfile:
  data = csv.DictReader(csvfile)
  for index, row in enumerate(data):
    for cell_key, cell_val in row.items():
      print(cell_key + '[' + str(index) + ']: ' + cell_val)
# records = [Record(app, row) for row in data]
# for i in range(0, len(records), 100):
# app.batch_create(records[i:i+100])

正しく読み込めている場合は,下記のような出力になります.

名前[0]: 佐藤 一郎
年齢[0]: 69
好きな標識_filepath[0]: hyousiki01/hyousiki01-001.png
名前[1]: 鈴木 二郎
年齢[1]: 35
好きな標識_filepath[1]: hyousiki01/hyousiki01-002.png;hyousiki01/hyousiki01-063.png
名前[2]: 高橋 三郎
年齢[2]: 51
好きな標識_filepath[2]: hyousiki01/hyousiki01-003.png

文字化けしている場合は,CSVファイルの文字コードがUTF-8になっているか確認してください.

ご教示ありがとうございます。

上記を試したところ、csvの4行目を読み込んでしまっていたようです。(名前[3]:)まで出てしまっていました。

修正し、同様の出力となりました。

 

post.pyを元に戻し実行しましたが、今度は下記のエラーが出ました。

C:\Users\XXXX\AppData\Local\Programs\Python\Python38\lib\site-packages\pykintone\account.py:48: YAMLLoadWarning: calling yaml.load() without Loader=… is deprecated, as the default Loader is unsafe. Please read https://msg.pyyaml.org/load for full details.
a_dict = yaml.load(f)

 

調べてみたところ、yaml.load(f)をyaml.load(f, Loader=yaml.SafeLoader)としなければいけないようなのですが、

pykintoneのaccount.pyを直接書き換えても問題ないのでしょうか

初心者様

お世話になっております.

はい,変更して問題ないかと思います.

ありがとうございます。

書き換えることで無事一括アップロードできました。

迅速な回答ありがとうございました。

今後ともよろしくお願いいたします。

何度も申し訳ございません。

アップロードできる拡張子に制限があるのでしょうか。

pdfを指定すると「message:Content-Typeを指定してください」と表示されます。

ナツ様

お世話になっております。

PDFなどはMIME Typeを指定しないといけないようですね.
確認不足で申し訳ございません.
下記で動作するかと思います.

import pykintone
from pykintone import model
import pykintone.structure_field as sf
import codecs
import csv
import mimetypes

class Record(model.kintoneModel):
  def __init__ (self, app, row):
    super(Record, self). __init__ ()
    for cell_key, cell_val in row.items():
      if '_filepath' in cell_key:
        setattr(self, cell_key.rstrip('_filepath'), [sf.File.upload(filepath, app, '', mimetypes.guess_type(filepath)) for filepath in cell_val.split(';')])
      else:
        setattr(self, cell_key, cell_val)

app = pykintone.load('account.yml').app()
with codecs.open('data.csv', 'r', 'utf-8') as csvfile:
  data = csv.DictReader(csvfile)
  records = [Record(app, row) for row in data]
for i in range(0, len(records), 100):
  app.batch_create(records[i:i+100])

何度も聞いてばかりで申し訳ございません。

ありがとうございます。

pdfやmp4もアップロードできました。