0

我想用存储在 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
4

1 回答 1

0

查看您的初始表 - 您的 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 作为填充数据库的一种方式。

于 2017-12-12T21:54:26.470 回答