for row in dfp.itertuples():
cursor.execute('''
INSERT INTO athletes(id, season, name)
VALUES (?,?,?)
''',
(
row.id,
row.season,
row.name,
)
'''
)
mysql.connector.errors.ProgrammingError: Not all parameters were used in the SQL statement.
I am getting this error because name is composed of first name and last name, so it is considering it as two different parameters when in reality it is only a single parameter. The same thing is happening in another table when I am using date (considering it as 3 parameters).
In pymysql, don't use ? as the parameter placeholders. Use %s.
cursor.execute('''INSERT INTO athletes(id, season, name) VALUES (%s,%s,%s)''',
(row.id, row.season, row.name,))
Related
rows_order = "SELECT COUNT (*) FROM 'Order'"
cursor.execute(rows_order)
ordernum = cursor.fetchall()
connection.commit()
cursor.execute("INSERT INTO 'Order' (OrderNo, CustomerID, Date, TotalCost) VALUES (?,?,?,?)", (
[ordernum], custid_Sorder, now, total_item_price))
This is what I am trying but this error popped up;
sqlite3.InterfaceError: Error binding parameter 0 - probably unsupported type.
How do I fix this? I want to make it so the OrderNo is = to the amount of orders before it, hence why I want to assign the orderno to it. (I am using sqlite3)
as you have only one value you need only fetchone
import sqlite3
con = sqlite3.connect("tutorial.db")
cursor = con.cursor()
rows_order = "SELECT COUNT (*) FROM 'Order'"
cursor.execute(rows_order)
ordernum = cursor.fetchone()[0]
cursor.execute("INSERT INTO 'Order' (OrderNo, CustomerID, Date, TotalCost) VALUES (?,?,?,?)", (
ordernum, custid_Sorder, now, total_item_price))
tl;dr Don't do this. Use an auto-incremented primary key.
fetchall returns all rows as a list, even if there is only one row.
Instead, use fetchone. This will return a single tuple which you can then select the first item. ordernum = cursor.fetchone()[0]
However, you appear to be writing a query to get the next ID. Using count(*) is wrong. If there are any gaps in OrderNo, for example if something gets deleted, it can return a duplicate. Consider [1, 3, 4]; count(*) will return 3. Use max(OrderNo) instead.
Furthermore, if you try to insert two orders at the same time you might get a race condition and one will try to duplicate the other.
process 1 process 2
select max(orderNo)
fetchone # 4
select max(orderNo)
fetchone # 4
insert into orders...
insert into orders... # duplicate OrderNo
To avoid this, you have to do both the select and insert in a transaction.
process 1 process 2
begin
select max(orderNo)...
fetchone # 4 begin
select max(orderNo)
fetchone
insert into orders... # wait
commit # wait
# 5
insert into orders...
commit
Better yet, do them as a single query.
insert into "Order" (OrderNo, CustomerID, Date, TotalCost)
select max(orderNo), ?, ?, ?
from "order"
Even better don't do it at all. There is a built-in mechanism to do this use an auto-incremented primary keys.
-- order is a keyword, pluralizing table names helps to avoid them
create table orders (
-- It is a special feature of SQLite that this will automatically be unique.
orderNo integer primary key
customerID int,
-- date is also a keyword, and vague. Use xAt.
orderedAt timestamp,
totalCost int
)
-- orderNo will automatically be set to a unique number
insert into orders (customerID, orderedAt, totalCost) values (...)
trying to insert values into one MySQL table using python.
First inserting values from csvfile; with:
sql = "INSERT INTO mydb.table(time,day,number)values %r" % tuple (values),)
cursor.execute(sql)
then insert into the same table and same row an other value
sql = "INSERT INTO mydb.table(name) values(%s)"
cursor.execute(sql)
with this i get the inserts in two different rows…
But i need to insert it into the same row without using sql = "INSERT INTO mydb.table(time,day,number,name)values %r" % tuple (values),)
Is there a way to insert values into the same row in two 'insert statements'?
INSERT will always add a new row. If you want to change values in this row, you have to specify a unique identifier (key) in the WHERE clause to access this row and use UPDATE or REPLACE instead.
When using REPLACE you need to be careful if your table contains an auto_increment column, since a new value will be generated.
I'm trying to use this code to update a table on mySQL, but I'm getting error with the update part
table_name = 'my_table'
sql_select_Query = """
INSERT {0} (age, city, gender,UniqueId)
VALUES ({1},{2},{3},{4})
ON DUPLICATE KEY UPDATE
age=VALUES(age,city=VALUES(city),gender=VALUES(gender),height=VALUES(height)
""".format(table_name, '877','2','1','2898989')
cursor = mySQLconnection .cursor()
cursor.execute(sql_select_Query)
mySQLconnection.commit()
For example, to update the city I get:
Unknow columns '877'
Hence it seems it is taking the value as a column name and search for then in my_table.
The correct way to use parameters with Python is to pass the values in the execute() call, not to interpolate the values into the SQL query.
Except for identifiers like the table name in your case.
sql_select_Query = """
INSERT `{0}` (age, city, gender, UniqueId)
VALUES (%s, %s, %s, %s)
ON DUPLICATE KEY UPDATE
age=VALUES(age), city=VALUES(city), gender=VALUES(gender)
""".format(table_name)
cursor.execute(sql_select_Query, ('877', '2', '1', '2898989'))
See also MySQL parameterized queries
You forgot the ) after VALUES(age. Maybe that was just a typo you made transcribing the question into Stack Overflow. I've fixed it in the example above.
Your INSERT statement sets the height column, but it's not part of the tuple you insert. I removed it in the example above. If you want height in the UPDATE clause, then you need to include it in the tuple and pass a value in the parameters.
Also I put back-quotes around the table name, just in case the table name is a reserved keyword or contains a space or something.
I am attempting to insert Excel spreadsheets into a Postgres DB using a Python script with psychopg2.
The problem is not all the spreadsheets have the same number of columns, and I need the insert statement to be flexible enough so I don't have to specify them by name.
My approach is to load the columns of the spreadsheet's header row into a tuple, and likewise with the values being inserted. So for example:
sql = ''''INSERT INTO my_table (%s) VALUES (%s);'''
cur.execute(sql, (cols, vals))
where 'cols' and 'vals' are both tuples.
'cols' can have 7, 9, 10, etc. entries, again depending on how many columns the spreadsheet had.
When I attempt to run this, I get:
psycopg2.ProgrammingError: syntax error at or near "'INSERT INTO my_table
(ARRAY['"
LINE 1: 'INSERT INTO my_table...
^
Not sure if the problem is in my calling syntax, or if you simply can't do what I'm trying to do.
There's an apostrophe ' at the beginning of your sql query.
''''INSERT INTO my_table (%s) VALUES (%s);'''
should be
'''INSERT INTO my_table (%s) VALUES (%s);'''
Edit: didn't realize you where trying to query columns dynamically. To do that, you should use text formatting. Asuming cols is a list:
sql = '''INSERT INTO my_table ({}) VALUES (%s)'''.format(','.join(cols))
Then, your execution would be:
cur.execute(sql, (vals,))
From the documentation , there is a way to insert data into table:
session.execute(
"""
INSERT INTO users (name, credits, user_id)
VALUES (%s, %s, %s)
""",
("John O'Reilly", 42, uuid.uuid1())
)
The column name have to be stated there. However, in my case, I have a dataframe which has only a header row and a row of data, for example:
"sepal_length" : 5.1,"sepal_width" : 3.5,"petal_length" : 1.4 ,"petal_width" : 0.2, "species" : "Iris" .
The user will provide the information for my API to connect to their particular Cassandra database's table which contain the columns name that stored in the dataframe. How can I insert the dataframe's data with respect to the column header mapped to the table without actually hardcode the column name like stated in the documentation since the headers are not the same for different cases.
I am trying to achieve something like this:
def insert_table(df, table_name, ... #connection details):
#Set up connection and session
session.execute(
"""
INSERT INTO table_name(#df's column header)
VALUES (%s, %s, %s)
""",
(#df's data for the only row)
)
I discovered this but I actually just need a simple insert operation.
You can get the Dataframe's column names with the following
column_names = list(my_dataframe.columns.values)
You could rewrite insert_table(...) to accept the list of column names as an argument.
For example, string substitution can be used to form the CQL statement:
cql_query = """
INSERT INTO {table_name} ({col_names})
VALUES (%s, %s, %s)
""".format(table_name="my_table", col_names=','.join(map(str, column_names)))
...