Please consider me to be a complete novice with psycopg2. My aim is to insert a 1D numpy array of dtype object (where the elements are only strings) into a postgresQL table. My main program saves the fields as strings in the numpy array. I then want to add each separate element to a column in the postgresqL table (or if you prefer, the the 1d Array is one row). Please note, the actual array has 36 elements! I need a method to put them all in.
I am using the cur.execute command although I believe there is some problem with the string conversion.
Array=np.empty(3,dype=object)
Array[0]='Hello'
Array[1]='Tea?'
Array[2]='Bye'
statement= "INSERT INTO testlog (field1,field2,field3) VALUES (%s)" #Etc.
cur.execute(statement,Array)
I get error:
cur.execute(statement,Array)
TypeError: not all arguments converted during string formatting
Also tried:
cur.executemany('INSERT INTO testlog VALUES ( %s )', [[v] for v in Array ]
Thanks
Your statement should contain place holder for all values:
statement= "INSERT INTO testlog (field1,field2,field3) VALUES (%s, %s, %s)"
For Example:
=# create table testlog (field1 varchar(50), field2 varchar(50), field3 varchar(50))`;
then in the python shell (note dtype not dype:
Array=np.empty(3,dtype=object)
Array[0]='Hello'
Array[1]='Tea?'
Array[2]='Bye'
sql = "INSERT INTO testlog (field1, field2, field3) VALUES (%s, %s, %s)"
cur.execute(sql, [f for f in Array])
conn.commit()
And in DB:
select * from testlog;
field1 | field2 | field3
--------+--------+--------
Hello | Tea? | Bye
(1 row)
Related
I'm using python's psycopg2 to create a table and the insert SQL string look like this
create_table ='''CREATE TABLE Datetime_Response(
rid BIGINT NOT NULL,
qid BIGINT,
roid BIGINT,
rotext VARCHAR(20)
)'''
INSERT INTO Datetime_Response (rid, qid, roid, rotext)
VALUES
(13020638659, 711799502, 4681912759, 07/21/2021)
But the output is weird. All the datetime string becomes 0. I tried both VARCHAR and TEST in the column rotext. They all show 0. I don't know what goes wrong.
(13020638659, 711799502, 4681912759, '0')
This is what the values looks like
values = list(entry.values())
print(values)
['13020638659', '711799502', '4681912759', '07/21/2021']
And this is what the insert syntax look like
values_str = "(%s)" % (', '.join( values ))
sql_string = "INSERT INTO %s (%s)\nVALUES\n %s" % (
table_name,
', '.join(columns),
values_str
)
print(sql_string)
INSERT INTO GZ_Datetime_Response (rid, qid, roid, rotext)
VALUES
(13020638659, 711799502, 4681912759, 07/21/2021)
Do it like this. Let the connector fill in the properly quoted values:
sql_string = "INSERT INTO %s (%s)\nVALUES (%s)" % (
table_name,
','.join(columns),
','.join(['?']*len(values))
)
cur.execute( sql_string, values )
Because 7 divided by 21 divided by 2021 is close to zero. / is integer division in Python 2 if both operands are an integer. Quote your value: 07/21/2021
Your query is open to SQL injection attacks by malicious users of your script!
values = list(entry.values())
print(values)
['13020638659', '711799502', '4681912759', '07/21/2021']
values_str = "(%s)" % (', '.join( values ))
sql_string = "INSERT INTO %s (%s)\nVALUES\n %s" % (
table_name,
', '.join(columns),
values_str
)
print(sql_string)
When using your string values to format your string, you will end up with:
INSERT INTO GZ_Datetime_Response (rid, qid, roid, rotext)
VALUES (13020638659, 711799502, 4681912759, 07/21/2021)
which does not contain any quotation marks. Use prepared statements to avoid problems caused by wrong types and to stop hackers from misusing your application/database.
If, for whatever reason, you cannot use prepared statements, make sure the string ends up as string in your final statement:
values = ['13020638659', '711799502', '4681912759', "'07/21/2021'"]
or INSERT INTO GZ_Datetime_Response (rid, qid, roid, rotext) VALUES (%s, %s, %s, '%s)
I'm new to python, programming in general, and trying to read a .dat file and insert the data into a postgres table.
I'm getting an error and I've googled but could not come up with a resolution. Hoping someone can point me to the right direction.
Ratings table:
UserID int
MovieID int
Rating float
Ratings.dat:
1::122::5::838985046
1::185::5::838983525
Below is my code:
import psycopg2
ratingsfile = open('ml-10M100K/ratings.dat', 'r')
for line in ratingsfile:
items = line.split('::')
for values in items:
curr.execute("INSERT INTO Ratings(UserID, MovieID, Rating)
VALUES (%s, %s, %s)", values)
conn.commit()
ratingsfile.close()
Error:
curr.execute("INSERT INTO Ratings(UserID, MovieID, Rating)
VALUES (%s, %s, %s)", values)
IndexError: string index out of range
You do not need to iterate through items. Instead you can assign the 3 %s variables as items[index] as follows:
import psycopg2
ratingsfile = open('ml-10M100K/ratings.dat', 'r')
for line in ratingsfile:
items = line.split('::')
curr.execute("INSERT INTO Ratings(UserID, MovieID, Rating) VALUES (%s, %s, %s)" % (items[0], items[1], items[2]))
conn.commit()
ratingsfile.close()
This assumes that, for example in your example Ratings.dat, that UserID is 1 (items[0]), MovieID is 122 and 185 (items[1]), and Rating is 5 (items[2]). The 9 digit integers at the end of each row can be accessed with items[3]
I have a list with data such as
infoarray[['1.', 'Name1', 'details1, '...', '...', '....'], ['2.', 'Name2, 'details2', '...', '...', '...'], ['3.', 'Name3', 'details3', '...', '...', '...']...]
I simply want to add the first 3 entries into a database table with the format
[PLACE],[NAME],[DETAILS]
Should be relatively simple. The data is already sorted, I would just simply have to append the first 3 elements of each inner array into my database. I tried the following code but I am getting an error.
//using pymysql
cur = conn.cursor()
cur.executemany("""
INSERT INTO
myTable
(place, name, details)
VALUES
(%s, %s, %s)
""", infoarray)
db.commit()
cur.close()
conn.close()
The error is "TypeError: not all arguments converted during string formatting"
which is assume means that my formatting is wrong. I am relatively new to python, so I am very familiar with the nuances of using pymysql.
This happens because you are formatting 3 values in your query, but passing more than 3 elements per arra yitem.
Try changing your executemany call to:
cur.executemany("""
INSERT INTO
myTable
(place, name, details)
VALUES
(%s, %s, %s)
""", [a[:3] for a in infoarray])
This way you will get only the first 3 elements in each array item and pass it to executemany
I am trying to insert into a postgresql database in python 3.6 and currently am trying to execute this line
cur.execute("INSERT INTO "+table_name+"(price, buy, sell, timestamp) VALUES (%s, %s, %s, %s)",(exchange_rate, buy_rate, sell_rate, date))
but every time it tries to run the table name has ' ' around it so it turns out like INSERT INTO table_name('12', ..., ..., ...) ... instead of
INSERT INTO table_name(12, ..., ..., ...) ... how can I make the string formatter leave the quotes out or remove them or something? It is causing a syntax error around the 12 because it doesn't need the single quotes.
Use it with triple quotes. Also you may pass table_name as a element of second parameter, too.
cur.execute("""INSERT INTO %s (price, buy, sell, timestamp) VALUES (%s, %s, %s, %s)""",(table_name, exchange_rate, buy_rate, sell_rate, date))
More detailed approach;
Triple qoutes give developers a change to write SQL query as multi-lines.
Also it allows you to use single and double qoutes without escaping from them. (It is beneficiary for complex SQL Queries but you don't need that on your case)
Use the new string formatting to have a clean representation. %s is explicitly converting to a string, you don't want that. Format chooses the most fitting type for you.
table_name = "myTable"
exchange_rate = 1
buy_rate = 2
sell_rate = 3
date = 123
x = "INSERT INTO {0} (price, buy, sell, timestamp) VALUES ({1}, {2}, {2}, {4})".format(
table_name, exchange_rate, buy_rate, sell_rate, date)
print x
>INSERT INTO myTable (price, buy, sell, timestamp) VALUES (1, 2, 2, 123)
I have a problem with MySQL and Python's MySQLdb when I try to INSERT more than one variable.
I have a table wordurl with three fields. The first one is an auto_increment ID, second and third should hold the values. Second and third fields are named word_id and url_id.
This is the code.
cursor.execute("INSERT INTO wordurl (word_id, url_id) VALUES (%s, %s)", (word_temp_id, url_temp_id))
When I try to INSERT only one value the code works, two not.
Error message:
(1064, "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 '),), (('2',),))' at line 1")
I also tried it with tripple ticks around the statement, the variables with and without bracket, without the field names and with the first id field included. I also tried with C-style-printf-stuff % (which isn't clever!). Nothing worked.
And you, glorious people on stackoverflow, you are my last hope :)
MySQL-Server is 5.5.9 on FreeBSD 8.2. Python version is 2.7:82508 on OSX Lion
Thanks in advance!
Steffen
UPDATE: I use cursor.fetchall() and cursor.fetchone() to get the IDs. Maybe this information is important.
Regarding your update:
AFAIK:
fetchall() returns a tuple with tuples inside. Those tuples inside are what you would get from fetchone(). You can image it like
fetchall() = (fetchone(), fetchtwo(), ...)
And fetchone also returns a tuple which has the actual variable values. This is why you can't simply insert the return value of fetchall().
Just to clarify: the insert statement you pasted, look like this when you fill in the value for max_price:
c.execute("""SELECT spam, eggs, sausage FROM breakfast WHERE price < %s""", (5,))
so the first %s is replaced with the first element of the tuple (5). Your insert statement looks like this:
cursor.execute("INSERT INTO wordurl (word_id, url_id) VALUES (%s, %s)", (((233L,),), ((3L,),)))
I can't make it more clear.
Did you try this:
cursor.execute("INSERT INTO wordurl (word_id, url_id) VALUES ('%s', '%s')" %(word_temp_id, url_temp_id))
It depends on what variables you're trying to insert, but on strings this is needed.
Notice the difference:
>>> word_temp_id = "bla1"
>>> url_temp_id = "bla2"
>>> query = "INSERT INTO wordurl (word_id, url_id) VALUES (%s, %s)" %(word_temp_id, url_temp_id)
>>> print query
INSERT INTO wordurl (word_id, url_id) VALUES (bla1, bla2)
>>> query = "INSERT INTO wordurl (word_id, url_id) VALUES ('%s', '%s')" %(word_temp_id, url_temp_id)
>>> print query
INSERT INTO wordurl (word_id, url_id) VALUES ('bla1', 'bla2')