Populate sqlite3 database from csv: Syntax error around '?' - python

Following a previous post concerning the population of a sqlite3 database from a csv file in python, I have used the code exactly as written but keep coming up with: Traceback (most recent call last):
File "Z:/KS4/Computer Science/OCR corsework/Task 1 Database/populate.py", line 10, in <module>
cursor.execute(query, data)
sqlite3.OperationalError: near "?": syntax error
This is the code:
import csv, sqlite3
connection = sqlite3.connect("TutorGroup.db")
with open ('studentsEmail-master.csv', 'r') as f:
r = csv.reader(f)
data = next(r)
query = 'insert into dbo.students ({0})'
query = query.format(','.join('?' * len(data)))
cursor = connection.cursor()
cursor.execute(query, data)
for data in reader:
cursor.execute(query, data)
cursor.commit()

https://www.sqlite.org/lang_insert.html
You need the word values in the query:
query = 'insert into dbo.students values ({0})'
# ^^^^^^

Related

Inserting csv into MySQL database with python library mysql.connector

I have trouble with insert of csv data into MySQL tabel with mysql.connector .
The code I use looks like this :
import mysql.connector
import csv
andreport = 'testowa.csv'
cnx = mysql.connector.connect(
user='xxxxx',
password='xxxxx',
host='xxxxxx',
database='xxxxx')
cursor = cnx.cursor()
with open(andreport, 'r') as csv_data:
for row in csv_data:
cursor.execute(
"INSERT INTO flex(date, Store, Vendor, Shelf)"
"VALUES({},{},{},{})", row)
cnx.commit()
cursor.close()
cnx.close()
print("Done")
The error I get :
C:\Users\Iw4n\PycharmProjects\Learning\venv\Scripts\python.exe C:/Users/Iw4n/PycharmProjects/Learning/Orange_android_MySQL_insertion.py
Traceback (most recent call last):
File "C:/Users/Iw4n/PycharmProjects/Learning/Orange_android_MySQL_insertion.py", line 15, in <module>
cursor.execute(
File "C:\Users\Iw4n\PycharmProjects\Learning\venv\lib\site-packages\mysql\connector\cursor.py", line 551, in execute
self._handle_result(self._connection.cmd_query(stmt))
File "C:\Users\Iw4n\PycharmProjects\Learning\venv\lib\site-packages\mysql\connector\connection.py", line 490, in cmd_query
result = self._handle_result(self._send_cmd(ServerCmd.QUERY, query))
File "C:\Users\Iw4n\PycharmProjects\Learning\venv\lib\site-packages\mysql\connector\connection.py", line 395, in _handle_result
raise errors.get_exception(packet)
mysql.connector.errors.ProgrammingError: 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '},{},{},{})' at line 1
When i wrapped {} into '' , as many rows as were in csv been inserted into datbase as {},{}
same story goes for %s if I use it , i got the same error as above, when it's wrapped in '' , %s is insetred into database.
I also found information to add f in fron of "INSERT~ but it did not help.
Can anyone give me some suggestion on how to overcome this and correctly insert data to MySQL ?
Final code that is working as intended :
import mysql.connector
import csv
andreport = 'testowa.csv'
cnx = mysql.connector.connect(
user='xxxxx',
password='xxxxx',
host='xxxxx',
database='xxxxx')
cursor = cnx.cursor()
with open(andreport, mode='r') as csv_data:
reader = csv.reader(csv_data, delimiter=';')
csv_data_list = list(reader)
for row in csv_data_list:
cursor.execute("""
INSERT INTO flex(
date, Agency, MediaSource, Campaign)
VALUES(%s,%s,%s,%s)""",
(row[0], row[1], row[2], row[3]))
cnx.commit()
cursor.close()
cnx.close()
print("Done")
I'm guessing that seems the problem is that you passed one argument (row) instead of four. So try this:
cursor.execute("""
INSERT INTO flex(date, Store, Vendor, Shelf)
VALUES(%s,%s,%s,%s)""",(row[0], row[1], row[2], row[3], ))
Looking at the documentation for MySQLCursor.excute() method, it seems like adding some %s as the parameters in your insert statement might fix this?
import mysql.connector
import csv
andreport = 'testowa.csv'
cnx = mysql.connector.connect(
user='xxxxx',
password='xxxxx',
host='xxxxxx',
database='xxxxx')
cursor = cnx.cursor()
insert_statement = (
"INSERT INTO flex(date, Store, Vendor, Shelf)"
"VALUES (%s, %s, %s, %s)"
)
with open(andreport, mode='r') as csv_data:
reader = csv.reader(csv_data, delimiter=';')
csv_data_list = list(reader)
for row in csv_data_list:
cursor.execute(insert_statement, row)
cnx.commit()
cursor.close()
cnx.close()
print("Done")
Let me know if this gets you anywhere, or if you see a new error!
Edit: updated CSV reading to convert to a list.

SQLITE error while trying to parse every table data with python

I am trying to print the entire table from all the tables inside of a db that I have created.
When I try to print all columns for each table I get an error and it seems that the script tries to parse trough one of the inside elements (first column and first row data) and therefore bringing back an error by saying that there is no such a table.
Here is my code:
import sqlite3
conn = sqlite3.connect('amazon_pages.db')
c = conn.cursor()
all_tables_list = c.execute("select name from sqlite_master where type = 'table'")
for table in all_tables_list:
argument_execute = 'SELECT * FROM ' + table[0]
print(argument_execute)
c.execute(argument_execute)
This is the error that I get:
SELECT * FROM Apple_charger
Traceback (most recent call last):
SELECT * FROM B07JGMC714
File "/Users/Amato/PycharmProjects/Refine/Amazon_pages_sql_database_creator.py", line 36, in <module>
c.execute(argument_execute)
sqlite3.OperationalError: no such table: B07JGMC714
Process finished with exit code 1
How do I print all the entire tables from the db?
fetch the result first:
all_tables_list = c.execute("select name from sqlite_master where type = 'table'")
rows = all_tables_list.fetchall()
for row in rows:
print(row)

TypeError: not enough arguments for format string while importing CSV to MySQL using Python

I wish to import my .csv file to a table 'testcsv' in MySQL using Python, but I'm unable to do so because I keep getting the following error:
Traceback (most recent call last):
File "<pyshell#9>", line 2, in <module>
cursor.execute(query,r)
File "C:\Python27\lib\site-packages\MySQLdb\cursors.py", line 184, in execute
query = query % db.literal(args)
TypeError: not enough arguments for format string
My code looks like this:
import csv
import MySQLdb
mydb = MySQLdb.connect(host='127.0.0.1',
port=3306,
user='root',
passwd='tulip',
db='frompython')
cursor = mydb.cursor()
csv_data = csv.reader(file('C:\Users\Tulip\Desktop\New_Sheet.csv'))
row_count = sum(1 for row in csv_data)
query = """INSERT INTO testcsv (number, name, marks) VALUES (%s, %s, %s)"""
for r in range(1, row_count):
cursor.execute(query,r)
I've tried every possible answer given to the related questions here, but none of them worked for me. Please help!
for r in range(1, row_count):
just iterates over numbers, i.e. in the first iteration r = 1. Remove the line defining row_count and get the actual rows:
for r in csv_data:

Writing a csv file into SQL Server database using python

I am trying to write a csv file into a table in SQL Server database using python. I am facing errors when I pass the parameters , but I don't face any error when I do it manually. Here is the code I am executing.
cur=cnxn.cursor() # Get the cursor
csv_data = csv.reader(file(Samplefile.csv')) # Read the csv
for rows in csv_data: # Iterate through csv
cur.execute("INSERT INTO MyTable(Col1,Col2,Col3,Col4) VALUES (?,?,?,?)",rows)
cnxn.commit()
Error:
pyodbc.DataError: ('22001', '[22001] [Microsoft][ODBC SQL Server Driver][SQL Server]String or binary data would be truncated. (8152) (SQLExecDirectW); [01000] [Microsoft][ODBC SQL Server Driver][SQL Server]The statement has been terminated. (3621)')
However when I insert the values manually. It works fine
cur.execute("INSERT INTO MyTable(Col1,Col2,Col3,Col4) VALUES (?,?,?,?)",'A','B','C','D')
I have ensured that the TABLE is there in the database, data types are consistent with the data I am passing. Connection and cursor are also correct. The data type of rows is "list"
Consider building the query dynamically to ensure the number of placeholders matches your table and CSV file format. Then it's just a matter of ensuring your table and CSV file are correct, instead of checking that you typed enough ? placeholders in your code.
The following example assumes
CSV file contains column names in the first line
Connection is already built
File name is test.csv
Table name is MyTable
Python 3
...
with open ('test.csv', 'r') as f:
reader = csv.reader(f)
columns = next(reader)
query = 'insert into MyTable({0}) values ({1})'
query = query.format(','.join(columns), ','.join('?' * len(columns)))
cursor = connection.cursor()
for data in reader:
cursor.execute(query, data)
cursor.commit()
If column names are not included in the file:
...
with open ('test.csv', 'r') as f:
reader = csv.reader(f)
data = next(reader)
query = 'insert into MyTable values ({0})'
query = query.format(','.join('?' * len(data)))
cursor = connection.cursor()
cursor.execute(query, data)
for data in reader:
cursor.execute(query, data)
cursor.commit()
I modified the code written above by Brian as follows since the one posted above wouldn't work on the delimited files that I was trying to upload. The line row.pop() can also be ignored as it was necessary only for the set of files that I was trying to upload.
import csv
def upload_table(path, filename, delim, cursor):
"""
Function to upload flat file to sqlserver
"""
tbl = filename.split('.')[0]
cnt = 0
with open (path + filename, 'r') as f:
reader = csv.reader(f, delimiter=delim)
for row in reader:
row.pop() # can be commented out
row = ['NULL' if val == '' else val for val in row]
row = [x.replace("'", "''") for x in row]
out = "'" + "', '".join(str(item) for item in row) + "'"
out = out.replace("'NULL'", 'NULL')
query = "INSERT INTO " + tbl + " VALUES (" + out + ")"
cursor.execute(query)
cnt = cnt + 1
if cnt % 10000 == 0:
cursor.commit()
cursor.commit()
print("Uploaded " + str(cnt) + " rows into table " + tbl + ".")
You can pass the columns as arguments. For example:
for rows in csv_data: # Iterate through csv
cur.execute("INSERT INTO MyTable(Col1,Col2,Col3,Col4) VALUES (?,?,?,?)", *rows)
If you are using MySqlHook in airflow , if cursor.execute() with params throw san error
TypeError: not all arguments converted during string formatting
use %s instead of ?
with open('/usr/local/airflow/files/ifsc_details.csv','r') as csv_file:
csv_reader = csv.reader(csv_file)
columns = next(csv_reader)
query = '''insert into ifsc_details({0}) values({1});'''
query = query.format(','.join(columns), ','.join(['%s'] * len(columns)))
mysql = MySqlHook(mysql_conn_id='local_mysql')
conn = mysql.get_conn()
cursor = conn.cursor()
for data in csv_reader:
cursor.execute(query, data)
cursor.commit()
I got it sorted out. The error was due to the size restriction restriction of table. It changed the column capacity like from col1 varchar(10) to col1 varchar(35) etc. Now it's working fine.
Here is the script and hope this works for you:
import pandas as pd
import pyodbc as pc
connection_string = "Driver=SQL Server;Server=localhost;Database={0};Trusted_Connection=Yes;"
cnxn = pc.connect(connection_string.format("DataBaseNameHere"), autocommit=True)
cur=cnxn.cursor()
df= pd.read_csv("your_filepath_and_filename_here.csv").fillna('')
query = 'insert into TableName({0}) values ({1})'
query = query.format(','.join(df.columns), ','.join('?' * len(df1.columns)))
cur.fast_executemany = True
cur.executemany(query, df.values.tolist())
cnxn.close()
You can also import data into SQL by using either:
The SQL Server Import and Export Wizard
SQL Server Integration Services (SSIS)
The OPENROWSET function
More details can be found on this webpage:
https://learn.microsoft.com/en-us/sql/relational-databases/import-export/import-data-from-excel-to-sql?view=sql-server-2017

sqlite3.OperationalError: no such column. But that's not a column

I seem to be getting a rather odd error. And, for the life of me I can't figure out what's wrong. But on a piece of SQLite code, I'm getting this error:
Traceback (most recent call last):
File "test.py", line 38, in <module>
populateTables()
File "test.py", line 20, in populateTables
curs.execute("SELECT * FROM tracks WHERE ISRC = " + line[8])
sqlite3.OperationalError: no such column: USTCZ0993316
The odd part is that USTCZ0993316 is a piece of data that I want to compare to. I don't know why it seems to think it is a column. Here is a much small version that gives the same issue.
import sqlite3
import csv
def tableSetup(name):
if(name=="tracks"):
curs.execute("CREATE TABLE tracks(id INT UNIQUE, name TINYTEXT, album_id INT, client_id INT, acr_record_num INT, ISRC TINYTEXT UNIQUE, track_length TINYTEXT, client_share FLOAT)")
def populateTables():
tracks_csv=csv.reader(open('tables/tracks.csv', 'rU'), delimiter=";", quotechar='"')
tracks_csv.next()
for line in tracks_csv:
curs.execute("SELECT * FROM tracks WHERE id = " + line[0])
if not curs.fetchall():
if "\"" in line[1]:
line[1]=line[1].replace("\"","'")
curs.execute("INSERT INTO tracks VALUES("+line[0]+",\""+line[1]+"\","+line[2]+","+line[3]+","+line[4]+",\""+line[5]+"\",\""+line[7]+"\","+line[12]+")")
override_csv=csv.reader(open('tables/artist_override.csv', 'rU'), delimiter=",", quotechar='"')
override_csv.next()
for line in override_csv:
curs.execute("SELECT * FROM tracks WHERE ISRC = " + line[8])
print curs.fetchone()
#Set required Table Names
tables = ["tracks"]
testOut=open('tables/testOut.txt','w')
conn = sqlite3.connect('tables/test.db')
curs = conn.cursor()
# Create table if they don't already exist
curs.execute("SELECT name FROM sqlite_master WHERE type='table'")
tableResults = curs.fetchall()
print
for table in tables:
if not any(table == result[0] for result in tableResults):
tableSetup(table)
populateTables()
conn.commit()
curs.close()
If it doesn't have quotes then it's a column or a number.
curs.execute("SELECT * FROM tracks WHERE ISRC = ?", (line[8],))
[Edit: "%s" isn't proper syntax. It should be "?". Also, if you're going to be condescending, at least be right about it.]

Categories