我创建了一个management command
,我想从ftp下载csv文件并在必要时更新数据库。
我的代码如下:
class Command(BaseCommand):
@staticmethod
def update_database(row):
code = row['CODE']
vat_number = row['BTWNR']
if code != "" and vat_number != "":
# pdb.set_trace()
print("Code: {0} --- BTW: {1}").format(code, vat_number)
def read_file(self):
path_to_relations_csv_file = "{0}/{1}".format(destination, file_name)
with open(path_to_relations_csv_file) as csvfile:
relations_reader = csv.DictReader(csvfile, delimiter=';')
for row in relations_reader:
self.update_database(row)
def handle(self, *args, **options):
# Open ftp connection
ftp = ftplib.FTP(ftp_host, ftp_username, ftp_password)
try:
ftp.cwd(source) # Goes to remote folder where the relations file is
os.chdir(destination) # Goes to local folder where the relations file will be downloaded
print("Switched to the directory successful. Current directory: {}".format(destination))
except OSError:
pass
except ftplib.error_perm:
print("Error: could not change to {0}".format(source))
sys.exit("Ending Application")
try:
# Get the file
relations = open(file_name, "wb") # Opens the remote file
ftp.retrbinary('RETR {0}'.format(file_name), relations.write) # Writes to the local file
print("File {0} downloaded successfully.".format(file_name))
relations.close() # Closes the local file
print("Local file closed.")
ftp.quit() # Closes the ftp connection
print("FTP Connection quited.")
try:
self.read_file()
except:
print("Error: Unable to read the file.")
except:
print("Error: File {0} could not be downloaded.".format(file_name))
但是在read_file
方法中,for循环给了我错误。如果我在for循环之前放置pdb.set_trace()
,我可以看到relations_reader
是<csv.DictReader object at 0x10e67a6a0>
,因此看起来没问题,但是如果我尝试循环它,它会转到except
并且它执行print("Error: Unable to read the file.")
路径正确。
如果使用python file_name.py
执行相同的代码作为单独的文件而不是python manage.py file_name
的命令,则一切正常。
知道我做错了什么吗?
答案 0 :(得分:0)
iterator should return strings, not bytes (did you open the file in text mode?)
表示您需要以其他方式打开CSV,而不是以您的方式打开CSV。
要解决此问题,请将打开模式和编码更改为适合您的csv文件的模式
open(path_to_relations_csv_file, "rt", encoding='utf-8') as csvfile: