Как обрабатывать пропущенные значения в файле CSV для столбца DECIMAL - PullRequest
0 голосов
/ 17 октября 2018

Я читаю данные в базу данных, используя pyodbc из файла .csv.

Один столбец определен как decimal(18,4) в SQL Server, но в этом столбце отсутствует значение.Поэтому, когда я пытаюсь вставить его, он выдает ошибку, говорящую, что строковый тип не может быть переведен в числовой тип.

Данные выглядят как

[A, B, C, , 10, 10.0, D, 10.00]

, как вы видите в позиции 4, естьотсутствует значение '', которое должно быть числом с плавающей запятой, например 4,3526

Я хочу прочитать эту строку в базе данных, где 4-й столбец определен как decimal(18,4), и он должен выглядеть как

A B C NULL 10 10.0 D 10.00

в базе данных.

РЕДАКТИРОВАТЬ:

Вот мой код

def load_data(c, infile, num_rows = None, db_schema = 'dbo',table_name = 'new_table'):

try:
    if num_rows:
        dat = pd.read_csv(infile, nrows = num_rows)
    else:
        dat = pd.read_csv(infile)

    l = dat.shape[1]
    c.executemany('INSERT INTO {}.{} VALUES {}'.format(db_schema,table_name,'(' + ', '.join(['?']*l) + ')'), dat.values.tolist())

except :
    with open(infile) as f:
        dat = csv.reader(f)
        i = 0
        for row in dat:
            if i == 0:
                l = len(row)
            else:
                c.execute('INSERT INTO {}.{} VALUES {}'.format(db_schema,table_name,'(' + ', '.join(['?']*l) + ')'), *row)

            if num_rows:
                if i == num_rows:
                    break
            i += 1

print(db_schema + '.' + table_name+' inserted successfully!')

Пожалуйста, игнорируйте ошибку отступа.

Спасибо.

Ответы [ 3 ]

0 голосов
/ 17 октября 2018

Я бы использовал NULLIF для вставки нуля, где значение = ''

declare @table table (c decimal(18,4))

declare @insert varchar(16) = ''

insert into @table
select NULLIF(@insert,'')
0 голосов
/ 18 октября 2018

Если метод pandas ' read_csv возвращает пустую строку для пропущенного значения, тогда велика вероятность, что ваш CSV-файл использует разделители запятых в «стиле пунктуации» (с пробелом после запятой) вместо «строгого»"разделители запятых (без лишних пробелов).

Рассмотрим" строгий "файл CSV

1,,price unknown
2,29.95,standard price

Код панд

df = pd.read_csv(r"C:\Users\Gord\Desktop\no_spaces.csv", header=None, prefix='column')
print(df)

производит

   column0  column1         column2
0        1      NaN   price unknown
1        2    29.95  standard price

Отсутствующее значение интерпретируется как NaN (не число).

Однако, если файл CSV содержит

1, , price unknown
2, 29.95, standard price

, тогда тот же код выдает

   column0 column1          column2
0        1            price unknown
1        2   29.95   standard price

Обратите внимание, что фактически отсутствующим значением является строка, содержащая один пробел (' ').Вы можете проверить это, используя print(df.to_dict()).

Если вы хотите, чтобы read_csv правильно проанализировал этот CSV-файл, вам нужно использовать sep=', ', чтобы разделитель полей содержал пробел

df = pd.read_csv(r"C:\Users\Gord\Desktop\with_spaces.csv", header=None, prefix='column', sep=', ', engine='python')
print(df)

что снова дает нам

   column0  column1         column2
0        1      NaN   price unknown
1        2    29.95  standard price
0 голосов
/ 17 октября 2018

Вы можете обработать это с помощью оператора case, чтобы получить пустые значения NULL.Что-то вроде:

declare @table table (c decimal(18,4))

declare @insert varchar(16) = ''

--insert into @table
--select @insert
--this would cause an error

insert into @table
select case when @insert = '' then null else @insert end 
--here we use a case to handle blanks

select * from @table
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...