Как я могу импортировать 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 в качестве средства для заполнения базы данных.