J'ai un fichier CSV et je veux l'importer en masse dans ma base de données sqlite3 en utilisant Python. La commande est ".import .....". Mais il semble que cela ne puisse pas fonctionner ainsi. Quelqu'un peut-il me donner un exemple de comment le faire dans sqlite3 ? J'utilise Windows, au cas où. Merci
Réponses
Trop de publicités?Merci beaucoup pour le bernie's réponse ! J'ai dû le modifier un peu - voici ce qui a fonctionné pour moi :
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()
Mon fichier texte (PC.txt) ressemble à ceci :
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()
"""
cd Final_Codes
python csv_to_db.py
CSV to SQL DB
"""
import csv
import sqlite3
import os
import fnmatch
UP_FOLDER = os.path.dirname(os.getcwd())
DATABASE_FOLDER = os.path.join(UP_FOLDER, "Databases")
DBNAME = "allCompanies_database.db"
def getBaseNameNoExt(givenPath):
"""Returns the basename of the file without the extension"""
filename = os.path.splitext(os.path.basename(givenPath))[0]
return filename
def find(pattern, path):
"""Utility to find files wrt a regex search"""
result = []
for root, dirs, files in os.walk(path):
for name in files:
if fnmatch.fnmatch(name, pattern):
result.append(os.path.join(root, name))
return result
if __name__ == "__main__":
Database_Path = os.path.join(DATABASE_FOLDER, DBNAME)
# change to 'sqlite:///your_filename.db'
csv_files = find('*.csv', DATABASE_FOLDER)
con = sqlite3.connect(Database_Path)
cur = con.cursor()
for each in csv_files:
with open(each, 'r') 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
TABLE_NAME = getBaseNameNoExt(each)
Cols = dr.fieldnames
numCols = len(Cols)
"""
for i in dr:
print(i.values())
"""
to_db = [tuple(i.values()) for i in dr]
print(TABLE_NAME)
# use your column names here
ColString = ','.join(Cols)
QuestionMarks = ["?"] * numCols
ToAdd = ','.join(QuestionMarks)
cur.execute(f"CREATE TABLE {TABLE_NAME} ({ColString});")
cur.executemany(
f"INSERT INTO {TABLE_NAME} ({ColString}) VALUES ({ToAdd});", to_db)
con.commit()
con.close()
print("Execution Complete!")
Cela peut s'avérer pratique lorsque vous avez beaucoup de fichiers csv dans un dossier que vous souhaitez convertir en un seul fichier .db en une seule fois !
Notez que vous ne devez pas connaître à l'avance les noms de fichiers, d'onglets ou de champs (noms de colonnes) !
Cool hein ? !
Si le fichier CSV doit être importé dans le cadre d'un programme python, alors, pour plus de simplicité et d'efficacité, vous pouvez utiliser os.system
selon les lignes suggérées par ce qui suit :
import os
cmd = """sqlite3 database.db <<< ".import input.csv mytable" """
rc = os.system(cmd)
print(rc)
Le fait est qu'en spécifiant le nom de fichier de la base de données, les données seront automatiquement sauvegardées, en supposant qu'il n'y ait pas d'erreurs de lecture.
Voici des solutions qui fonctionneront si votre fichier CSV est très volumineux. Utilisez to_sql
comme suggéré par une autre réponse, mais définissez la taille des morceaux pour qu'il n'essaie pas de traiter tout le fichier en une seule fois.
import sqlite3
import pandas as pd
conn = sqlite3.connect('my_data.db')
c = conn.cursor()
users = pd.read_csv('users.csv')
users.to_sql('users', conn, if_exists='append', index = False, chunksize = 10000)
Vous pouvez également utiliser Dask, comme décrit aquí pour écrire un grand nombre de DataFrames Pandas en parallèle :
dto_sql = dask.delayed(pd.DataFrame.to_sql)
out = [dto_sql(d, 'table_name', db_url, if_exists='append', index=True)
for d in ddf.to_delayed()]
dask.compute(*out)
Ver aquí pour plus de détails.
4 votes
Veuillez fournir le réel qui n'a pas fonctionné et la commande réel message d'erreur. "import...." peut être n'importe quoi. "cannot work" est trop vague pour que nous puissions le deviner. Sans détails, nous ne pouvons pas vous aider.
3 votes
La commande réelle comme je l'ai dit est ".import" et il dit erreur de syntaxe nouveau ".import".
14 votes
Veuillez afficher la commande réelle dans la question. Veuillez afficher le message d'erreur réel dans la question. Veuillez ne pas ajouter de commentaires qui ne font que répéter les choses. Veuillez mettre à jour la question avec un copier-coller de ce que vous faites réellement.
0 votes
FWIW
.import
est la commande pour importer des fichiers dans le shell interactif SQLite.