Импорт CSV-файла в таблицу базы данных sqlite3 с помощью Python
У меня есть CSV-файл, и я хочу массово импортировать этот файл в мою базу данных sqlite3 с помощью Python. команда ".импорт.....". но кажется, что это не может работать так. Может ли кто-нибудь дать мне пример того, как это сделать в sqlite3? Я использую windows на всякий случай. Спасибо
8 ответов:
import csv, sqlite3 con = sqlite3.connect(":memory:") cur = con.cursor() cur.execute("CREATE TABLE t (col1, col2);") # use your column names here with open('data.csv','rb') as fin: # `with` statement available in 2.5+ # csv.DictReader uses first line in file for column headings by default dr = csv.DictReader(fin) # comma is default delimiter to_db = [(i['col1'], i['col2']) for i in dr] cur.executemany("INSERT INTO t (col1, col2) VALUES (?, ?);", to_db) con.commit() con.close()
создание соединения sqlite с файлом на диске остается в качестве упражнения для читателя ... но теперь есть два лайнера, что стало возможным благодаря библиотеке панд
df = pandas.read_csv(csvfile) df.to_sql(table_name, conn, if_exists='append', index=False)
на
.import
command-это функция средства командной строки sqlite3. Чтобы сделать это в Python, вы должны просто загрузить данные, используя любые средства Python, такие как csv модуль, и вставка данных, как обычно.таким образом, вы также можете контролировать, какие типы вставляются, а не полагаться на внешне недокументированное поведение sqlite3.
мои 2 цента (более общая):
import csv, sqlite3 import logging def _get_col_datatypes(fin): dr = csv.DictReader(fin) # comma is default delimiter fieldTypes = {} for entry in dr: feildslLeft = [f for f in dr.fieldnames if f not in fieldTypes.keys()] if not feildslLeft: break # We're done for field in feildslLeft: data = entry[field] # Need data to decide if len(data) == 0: continue if data.isdigit(): fieldTypes[field] = "INTEGER" else: fieldTypes[field] = "TEXT" # TODO: Currently there's no support for DATE in sqllite if len(feildslLeft) > 0: raise Exception("Failed to find all the columns data types - Maybe some are empty?") return fieldTypes def escapingGenerator(f): for line in f: yield line.encode("ascii", "xmlcharrefreplace").decode("ascii") def csvToDb(csvFile, outputToFile = False): # TODO: implement output to file with open(csvFile,mode='r', encoding="ISO-8859-1") as fin: dt = _get_col_datatypes(fin) fin.seek(0) reader = csv.DictReader(fin) # Keep the order of the columns name just as in the CSV fields = reader.fieldnames cols = [] # Set field and type for f in fields: cols.append("%s %s" % (f, dt[f])) # Generate create table statement: stmt = "CREATE TABLE ads (%s)" % ",".join(cols) con = sqlite3.connect(":memory:") cur = con.cursor() cur.execute(stmt) fin.seek(0) reader = csv.reader(escapingGenerator(fin)) # Generate insert statement: stmt = "INSERT INTO ads VALUES(%s);" % ','.join('?' * len(cols)) cur.executemany(stmt, reader) con.commit() return con
большое спасибо за ответ! Пришлось немного подправить его - вот что сработало для меня:
import csv, sqlite3 conn = sqlite3.connect("pcfc.sl3") curs = conn.cursor() curs.execute("CREATE TABLE PCFC (id INTEGER PRIMARY KEY, type INTEGER, term TEXT, definition TEXT);") reader = csv.reader(open('PC.txt', 'r'), delimiter='|') for row in reader: to_db = [unicode(row[0], "utf8"), unicode(row[1], "utf8"), unicode(row[2], "utf8")] curs.execute("INSERT INTO PCFC (type, term, definition) VALUES (?, ?, ?);", to_db) conn.commit()
мой текстовый файл (компьютер.txt) выглядит так:
1 | Term 1 | Definition 1 2 | Term 2 | Definition 2 3 | Term 3 | Definition 3
#!/usr/bin/python # -*- coding: utf-8 -*- import sys, csv, sqlite3 def main(): con = sqlite3.connect(sys.argv[1]) # database file input cur = con.cursor() cur.executescript(""" DROP TABLE IF EXISTS t; CREATE TABLE t (COL1 TEXT, COL2 TEXT); """) # checks to see if table exists and makes a fresh table. with open(sys.argv[2], "rb") as f: # CSV file input reader = csv.reader(f, delimiter=',') # no header information with delimiter for row in reader: to_db = [unicode(row[0], "utf8"), unicode(row[1], "utf8")] # Appends data from CSV file representing and handling of text cur.execute("INSERT INTO neto (COL1, COL2) VALUES(?, ?);", to_db) con.commit() con.close() # closes connection to database if __name__=='__main__': main()
вы можете сделать это с помощью
blaze
&odo
эффективноimport blaze csv_path = 'data.csv' bz.odo(csv_path, 'sqlite:///data.db::data')
Odo сохранит csv-файл в
data.db
(база данных sqlite) под схемойdata
или
odo
напрямую, безblaze
. В любом случае это нормально. Прочтите это документация
на основе решения Guy L (люблю его), но может обрабатывать экранированные поля.
import csv, sqlite3 def _get_col_datatypes(fin): dr = csv.DictReader(fin) # comma is default delimiter fieldTypes = {} for entry in dr: feildslLeft = [f for f in dr.fieldnames if f not in fieldTypes.keys()] if not feildslLeft: break # We're done for field in feildslLeft: data = entry[field] # Need data to decide if len(data) == 0: continue if data.isdigit(): fieldTypes[field] = "INTEGER" else: fieldTypes[field] = "TEXT" # TODO: Currently there's no support for DATE in sqllite if len(feildslLeft) > 0: raise Exception("Failed to find all the columns data types - Maybe some are empty?") return fieldTypes def escapingGenerator(f): for line in f: yield line.encode("ascii", "xmlcharrefreplace").decode("ascii") def csvToDb(csvFile,dbFile,tablename, outputToFile = False): # TODO: implement output to file with open(csvFile,mode='r', encoding="ISO-8859-1") as fin: dt = _get_col_datatypes(fin) fin.seek(0) reader = csv.DictReader(fin) # Keep the order of the columns name just as in the CSV fields = reader.fieldnames cols = [] # Set field and type for f in fields: cols.append("\"%s\" %s" % (f, dt[f])) # Generate create table statement: stmt = "create table if not exists \"" + tablename + "\" (%s)" % ",".join(cols) print(stmt) con = sqlite3.connect(dbFile) cur = con.cursor() cur.execute(stmt) fin.seek(0) reader = csv.reader(escapingGenerator(fin)) # Generate insert statement: stmt = "INSERT INTO \"" + tablename + "\" VALUES(%s);" % ','.join('?' * len(cols)) cur.executemany(stmt, reader) con.commit() con.close()