Как я могу импортировать CSV-файл без первичного ключа в sqlite3

Я хочу заполнить новую базу данных исходными данными, хранящимися в CSV-файлах. Я попытался использовать odo для заполнения существующей таблицы содержимым файла CSV. Мои файлы не имеют первичного ключа, и количество столбцов не совпадает, поскольку в базе данных определены дополнительные столбцы.

Как я могу использовать odo для достижения этой цели?

from sqlalchemy import Column, String, Integer, create_engine
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Test(Base):
    __tablename__ = 'testtable'

    uid = Column(Integer, primary_key=True)
    colA = Column(String(50))
    colB = Column(String(50))
    comment = Column(String(100))

engine = create_engine('sqlite:///testdb.db')
Base.metadata.create_all(engine)

Мой CSV-файл выглядит так:

col A;col B
aa;bb
ax;bx

Это не работает:

from odo import odo
odo('csvfile.csv', 
    'sqlite:///testdb.db::testtable', 
    has_header=True)

Сообщение об ошибке:

expected 4 columns but found 3 - filling the rest with NULL
INSERT failed: datatype mismatch

1 ответ

Глядя на вашу исходную таблицу - ваш CSV поставляется только с двумя столбцами и третий (вероятно, первичный ключ) генерируется. Убедитесь, что комментарий не требуется (или используйте текст по умолчанию, как в примере ниже), затем явно поместите каждое значение в столбец базы данных или рассмотрите возможность удаления этого столбца во время первоначального заполнения и воссоздания после первоначального заполнения.

Вот пример явного размещения каждого значения в соответствующем столбце. Это решает проблему sqlite3, не выравнивая количество входов, обеспеченных доступными столбцами:

import csv
# just my flavor...    

with open('csvfile.csv', 'r') as csvfile:
    # Next three lines detect dialect
    dialect = csv.Sniffer().sniff(csvfile.read(1024))
    # csvfile.seek(1,0) skips the first line of the file containing headers
    csvfile.seek(1,0)
    reader = csv.reader(csvfile, dialect)

for line in reader:
    A = line[0]
    B = line[1]
    rec = Test(colA=A, colB=B,comment='default text')
    session.add(rec)
    session.commit()

Чтобы избежать проблемы, не используйте комментарии, пока база данных не будет заполнена:

class Test(Base):
    __tablename__ = 'testtable'
    uid = Column(Integer, primary_key=True)
    colA = Column(String(50))
    colB = Column(String(50))

Это должно позволить использовать ваш odo в качестве средства для заполнения базы данных.

Другие вопросы по тегам