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.
Related
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,))
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 have a set of data in a list, embedded into a dictionary as:
{'list1': ['Freddy','36','fred','123f','2017/04/25'],
'list2':['Tara','25','mtara','123t','2018/03/22']}
Ref notations:
{ key1: [name, age,nickname, userid, account_created_date],
..key2:[name, age,nickname, userid, account_created_date] }
All the data is inserted in variables in a Python function, one for each, as described above. When I call the function I would get the output right-away as
Output:
Freddy
Tara
But when I try to insert the data into a sqlite database, I get the output in the following manner:
Output:
F
R
E
D
D
Y
T
A
R
A
Code:
conn = sqlite3.connect(dbPath)
cur = conn.cursor()
results = cur.executemany("INSERT INTO Field (Field1) VALUES (?)", name)
conn.commit()
Requesting your assistance on this issue. Your help is much appreciated. Thank You.
New Answer
To suit your dataset more directly. You need a list of dictionaries, not a dictionary of lists because each dictionary has the column name as the key and a value associated with that column (key).
names = [{'name': "Freddy"}, {'name': "Joan"}]
results = c.executemany("INSERT INTO names ('name') VALUES (:name)", names)
The rest of the SQLite3 code working, this outputs:
Freddy
Joan
Option to Use a List of Tuples
You can also use a list of tuples. If you're not using a dictionary, you need to make sure each row is in tuple form. You need each of these tuples in a list. You need to call this list in the executemany function after the SQL query.
Essential code:
names = [("Freddy",), ("Joan",)]
results = c.executemany("INSERT INTO names (name) VALUES (?)", names)
Output:
Freddy
Joan
So make sure each entry is in tuple or dictionary form. Then put these tuples or dictionaries into a list. If it's in dictionary form, you cannot use the '?' placeholder. Use ':key_name' for each placeholder. (There might be a different option here, but I haven't found it yet).
Original Response
I suspect that executemany(...) should be execute(...). I haven't used SQLite3 in a while, so I'll test it now to make sure and then get back to you.
Update 1:
I remember the "?'s" needing to be sent in tuple form. I.e.
cur.executemany("INSERT INTO Field (Field1) VALUES (?)", name)
needs to be at least
cur.executemany("INSERT INTO Field (Field1) VALUES (?)", (name, ...))
But I've only gotten the execute() (and not executemany()) to work, with this, else it's back to the same error. So, here's my working code so far:
cur.execute("INSERT INTO Field (Field1) VALUES (?)", (name,))
It gave F, R, E, D, D, Y because it was reading each letter as values in the tuple. If it was in tuple form, it would read "Freddy" all in one go. But I'm still having issues with the executemany(), which I think works differently than we think it does.
Update 2:
Here's what I got to work. You need to make sure each row is in tuple form. You need each of these tuples in a list. You need to call this list in the executemany function after the SQL query.
Essential code:
names = [("Freddy",), ("Joan",)]
results = c.executemany("INSERT INTO names (name) VALUES (?)", names)
Full code:
import sqlite3
conn = sqlite3.connect('test.db')
c = conn.cursor()
# Create table
c.execute('''CREATE TABLE IF NOT EXISTS names
(name text)''')
names = [("Freddy",), ("Joan",)]
results = c.executemany("INSERT INTO names (name) VALUES (?)", names)
conn.commit()
for row in c.execute('SELECT * FROM names'):
print(row[0])
This prints out:
Freddy
Joan
Update 3:
I've updated it to suit your dataset more directly. You need a list of dictionaries, not a dictionary of lists because each dictionary has the column name as the key and a value associated with that column (key).
Here's some more code, I've gotten to work.
names = [{'name': "Freddy"}, {'name': "Joan"}]
results = c.executemany("INSERT INTO names ('name') VALUES (:name)", names)
With the rest of the code as it was, it outputs:
Freddy
Joan
(Inspired from this answer.)
you might consider to change
results = cur.executemany("INSERT INTO Field (Field1) VALUES (?)", name)
to
results = cur.executemany("INSERT INTO Field (Field1) VALUES (?)", (name))
since the expected parameter is a tuple, the string is not considered as a whole but splited
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)))
...
I'm worndering how I can add 2 rows, of which 1 depends on another, in 1 transaction.
INSERT INTO users (username) VALUES ('malcom.reynolds')
INSERT INTO spaceships (name, owner)
VALUES ('Serenity', <<Malcom Reynold's row ID>>)
Reason I an doing is that the library I'm using does not return the rowid, and I need to commit the transaction as less as possible as I'm adding over a few million records!
Just for the record I'm using:
SQL Server 2008
Python
pyodbc
Any idea? Would be really awesome :)
You can do this in one batch statement:
declare #key as int;
insert into users (username)
values ('malcom.reynolds');
set #key = (select scope_identity());
insert into spaceships (name, owner)
values ('Serenity', #key)
Look at http://msdn.microsoft.com/en-us/library/aa259185%28SQL.80%29.aspx
INSERT INTO users (username) VALUES ('malcom.reynolds');
INSERT INTO spaceships (name, owner)
VALUES ('Serenity', SCOPE_IDENTITY() )
You can use the T-SQL scope_identity to return the new ID from the first INSERT statement.
Before your first INSERT, declare a variable to hold the value of the new ID:
DECLARE #ReturnValue int;
Right after your first INSERT, add this to set the value of that variable:
SELECT #ReturnValue = scope_identity()
Then, you can use the #ReturnValue variable in your second INSERT in place of :
INSERT INTO spaceships (name, owner)
VALUES ('Serenity', #ReturnValue)
Or you can use OUTPUT. This is hadnier when you need to return more than one field or are doing a multitrow insert to begin with. You can use a table variable if you are doing multiple rows instead of an int variable.
DECLARE #key int
insert into users (username)
output inserted.userid
values ('malcom.reynolds');
insert into spaceships (name, owner)
values ('Serenity', #key)