值太长,无法更改类型字符(25)

时间:2019-12-11 11:18:57

标签: django sqlite django-models django-views django-postgresql

我在将CSV文件上传到数据库时遇到麻烦,当我尝试上传该文件时,字段performance_exccy收到“对于类型字符变化(25)来说值太长”的错误消息(请参见下文,我的Django模型)。当我从SQLite切换到PostgreSQL(使用ElephantSQL)时,开始出现此错误消息,使用SQLite可以完美地完成上传。

引起问题的值是0.000000000000000000,它有20个字符,但是在我的模型中,我定义了max_digit = 40dec_places =20-因此位数不应该成为问题。 我还注意到,上载错误不是从CSV文件的第一行开始,而是从第12行开始,各行之前的长度类似。

我的模特:

class Testdata3(models.Model):
    key = models.CharField(max_length=100, primary_key=True)
    mnemonic = models.CharField(max_length=50)
    assetclass = models.CharField(max_length=25)
    value = models.DecimalField(max_digits=25,decimal_places=10)
    performance = models.DecimalField(max_digits=40,decimal_places=20)
    performance_exccy = models.DecimalField(max_digits=40,decimal_places=20)
    performance_abs = models.DecimalField(max_digits=40,decimal_places=20)
    performance_abs_exccy = models.DecimalField(max_digits=40,decimal_places=20)
    date = models.DateField()

    def __str__(self):
        return self.key

我的观点:

def file_upload(request):
    template = "upload.html"
    prompt = {
        'order': 'Order of the CSV should be "placeholder_1", "placeholder_2", "placeholder_3" '
    }

    if request.method == "GET":
        return render(request, template, prompt)

    csv_file = request.FILES['file']

    if not csv_file.name.endswith('.csv'):
        messages.error(request, 'This is not a csv file')

    data_set = csv_file.read().decode('UTF-8')

    io_string = io.StringIO(data_set)

    #Ignores header row by jumping to next row
    next(io_string) 

    for column in csv.reader(io_string, delimiter=';', quotechar="|"):
        # Check if csv-row is empty, if true jump to next iteration/row
        if all(elem == "" for elem in column):
            next
        else:
            _, created = Testdata3.objects.update_or_create(
                key = column[0],

                defaults = {
                'key' : column[0],
                # Get everything after the date part in the primary key
                'mnemonic': re.findall(r'AMCS#[0-9]*(.*)', column[0])[0],
                # Create datetime object from a string
                'date' : datetime.datetime.strptime(column[6], '%d/%m/%Y'),
                'assetclass' : column[10],
                'value' : column[16], 
                'performance' : column[19],
                'performance_abs' : column[20],
                'performance_abs_exccy' : column[30],
                'performance_exccy' : column[31],
                }
            )
        context = {}

    return render(request, template, context)

2 个答案:

答案 0 :(得分:0)

  

PostgreSQL 建议,如果您不想强制使用最大值,则只对可变宽度的字符串使用文本类型。   使用文本不会影响性能。

https://github.com/npgsql/efcore.pg/issues/342

答案 1 :(得分:0)

我发现了问题: 我检查了具有多个csv文件的上传,并发现当assetclass字段包含字符串Sonstige Vermögensgegenstände时始终会发生错误。因此,我在assetclass视图中注释了file_upload字段,突然间我便能够将数据导入数据库。该错误的原因是,资产类别字段的最大长度为25,而字符串Sonstige Vermögensgegenstände的长度为30个字符。因此,尽管django告诉我问题与字段performance_exccy有关,但实际上是由于assetclass字段引起的。