How to insert variable data into postgresql? [duplicate] - python

This question already has answers here:
How to use variables in SQL statement in Python?
(5 answers)
Closed 11 months ago.
I have created a database with postgresql. I am able to insert string values into table. I want to insert variable data into table. But I am getting invalid syntax for integer error.
import psycopg2
temp= 30
hum = 50
conn = psycopg2.connect('dbname=test')
cur = conn.cursor()
cur.execute("INSERT INTO DHT11 (temperature, humidity) VALUES('temp','hum')")
conn.commit()
cur.execute('select * from DHT11')
results = cur.fetchall()
for result in results:
print(result)

Please use parameters when passing values into your queries, like so:
import psycopg2
temp= 30
hum = 50
conn = psycopg2.connect('dbname=test')
cur = conn.cursor()
cur.execute("INSERT INTO DHT11 (temperature, humidity) VALUES(%s, %s)", (temp, hum))
conn.commit()
cur.execute('select * from DHT11')
results = cur.fetchall()
for result in results:
print(result)
When you use this form you protect yourself from SQL Injection. The driver also takes care of escaping and quoting the values you are passing into the query.
In your original code, putting 'temp' and 'hum' in your query string tried to put the literal values, temp and hum into your table. The strings are not integers.

Related

python sqlite query selecting text padded with multiple zeros

I had trouble with selecting TEXT data type padded with zeros in front.
Found out there's something wrong with my DB.
My multiple tries and all of answers by peers should all should work.
Thanks #snakecharmerb and #forpas for pointing out for possible flaw in DB.
For example, code column includes
000001, 000010, 000300 ...
There are also a multiple of Data with same code.
code date
000030 20210101
000030 20210102
000030 20210103
000030 20210104
000030 20210105
...
I need to loop through a list so I tried multiple ways of using f-string, but it did not work.
con = sqlite3.connect("DIRECTORY")
cur = con.cursor()
code = '000030' // does not work
code = 000030 // forbidden by python 3.7
query = cur.execute(f"SELECT * From TABLE where code is {code}") // should work
query = cur.execute(f"SELECT * From TABLE where code is '{code}'") // should work
query = cur.execute(f'SELECT * From TABLE where code is "{code}"') // should work
query = cur.execute('SELECT * From TABLE where code = ?',('000030',)) // should work
query = cur.execute("SELECT * From TABLE where code is 000030") // works but cannot loop through a list
Also tried replacing 'is' with '=', '=='. All should work.
Whatever the data type of the column code is, this query should work:
query = cur.execute("SELECT * From TABLE where code = ?", ("000030",))
Try with implicit conversions to integers for the column value and the parameter that you pass:
query = cur.execute("SELECT * From TABLE where code + 0 = ? + 0", ("000030",))
If this does not work, it means that the values of the column code are not like the ones that you posted in your question.
Here's an working example:
import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute("""CREATE TABLE test (code TEXT)""")
for i in range(0, 100, 10):
cur.execute("""INSERT INTO test (code) VALUES (?)""", (str(i).zfill(5),))
conn.commit()
cur.execute("""SELECT * FROM test""")
for row in cur:
print(row)
print()
cur.execute("""SELECT code FROM test WHERE code = ?""", ('00030',))
for row in cur:
print(row)
print()
conn.close()
Output
('00000',)
('00010',)
('00020',)
('00030',)
('00040',)
('00050',)
('00060',)
('00070',)
('00080',)
('00090',)
('00030',)

How do I use MySQLs Point type from Python?

I have written a Python game that uses positions on a grid.
I want to store these positions in MySQL.
I have a MySQL database table that uses a POINT type.
I have imported the mysql.connector library.
I believe I should write this:
query = "INSERT INTO player_position(coordinate) VALUES (%s)"
values = (GeomFromText('Point(39 55)')
cursor.execute(query, values)
db.commit()
I get this error:
name 'GeomFromText' is not defined
Is this the correct way of doing this?
If it is, where is GeomFromText defined?
I think that GeomFromText is unsupported and not well documented. Instead, you could try as follows:
query = "INSERT INTO player_position(coordinate) VALUES Point(39, 55);"
cursor.execute(query)
db.commit()
or
query = """INSERT INTO player_position(coordinate) VALUES (PointFromWKB(point(%s, %s)))"""
cursor.execute(query, (39, 55))
db.commit()
x = 39
y = 55
coordinates = f"Point({x} {y})"
query = "INSERT INTO player_position(coordinates) " \
"VALUES ST_PointFromText(%(coordinates)s)"
cursor.execute(query, {"coordinates": coordinates})
db.commit()
Using an f-string to format the coordinates to the "Point(x y)" format. str.format() can also be used instead.
Then ST_PointFromText to parse it in MySQL.

How can I insert a list returned from pyodbc mssql query into mysql through stored procedure using pymysql

I am pulling data from a MSSQL db using pyodbc which returns my data set in a list. This data then needs to be transferred into a MySQL db. I have written the following stored procedure in MySQL.
CREATE DEFINER=`root`#`localhost` PROCEDURE `sp_int_pmt`(
IN pmtamt DECIMAL(16,10),
IN pmtdt DATETIME,
IN propmtref VARCHAR(128),
IN rtdinv_id INT(11)
)
BEGIN
INSERT INTO ay_financials.payment
(
pmtamt,
pmtdt,
propmtref,
rtdinv_id
)
VALUES
(
pmtamt,
pmtdt,
propmtref,
rtdinv_id
);
END
The procedure works fine if I am inserting one record at the time. So, for now, I am iterating over the list from my MSSQL query and call the procedure for each record. I am using this code:
cursor = cnxn.cursor()
cursor.execute(""" SELECT *
FROM [%s].[dbo].[pmt]
WHERE pmtdt BETWEEN '2018-01-01' AND '2018-12-31'""" %(database))
a = cursor.fetchmany(25)
cnxn.close()
import pymysql
# MySQL configurations
un = 'ssssssss'
pw = '****************'
db = 'ay_fnls'
h = '100.100.100.100'
conn = pymysql.connect(host=h, user=un, password=pw, db=db, cursorclass=pymysql.cursors.DictCursor)
cur = conn.cursor()
for ay in a:
cur.callproc('sp_int_pmt',(ay.pmtamt,ay.pmtdt,ay.propmtref,ay.rtdinv_id))
conn.commit()
The problem I will have in production is this list will contain 10,000-100,000 every day. Iterating over that data doesn't seem like an optimized way to handle this.
How can I use the full list from the MSSQL query, call the MySQL procedure one time and insert all the relevant data?
How can I use the full list from the MSSQL query, call the MySQL procedure one time and insert all the relevant data?
You can't do that with your stored procedure as written. It will only insert one row at a time, so to insert n rows you would have to call it n times.
Also, as far as I know you can't modify the stored procedure to insert n rows without using a temporary table or some other workaround because MySQL does not support table-valued parameters to stored procedures.
You can, however, insert multiple rows at once if you use a regular INSERT statement and .executemany. pymysql will bundle the inserts into one or more multi-row inserts
mssql_crsr = mssql_cnxn.cursor()
mssql_stmt = """\
SELECT 1 AS id, N'Alfa' AS txt
UNION ALL
SELECT 2 AS id, N'Bravo' AS txt
UNION ALL
SELECT 3 AS id, N'Charlie' AS txt
"""
mssql_crsr.execute(mssql_stmt)
mssql_rows = []
while True:
row = mssql_crsr.fetchone()
if row:
mssql_rows.append(tuple(row))
else:
break
mysql_cnxn = pymysql.connect(host='localhost', port=3307,
user='root', password='_whatever_',
db='mydb', autocommit=True)
mysql_crsr = mysql_cnxn.cursor()
mysql_stmt = "INSERT INTO stuff (id, txt) VALUES (%s, %s)"
mysql_crsr.executemany(mysql_stmt, mssql_rows)
The above code produces the following in the MySQL general_log
190430 10:00:53 4 Connect root#localhost on mydb
4 Query INSERT INTO stuff (id, txt) VALUES (1, 'Alfa'),(2, 'Bravo'),(3, 'Charlie')
4 Quit
Note that pymysql cannot bundle calls to a stored procedure in the same way, so if you were to use
mysql_stmt = "CALL stuff_one(%s, %s)"
instead of a regular INSERT then the general_log would contain
190430 9:47:10 3 Connect root#localhost on mydb
3 Query CALL stuff_one(1, 'Alfa')
3 Query CALL stuff_one(2, 'Bravo')
3 Query CALL stuff_one(3, 'Charlie')
3 Quit

error: list index out of range. Python variable obtained using cur.fetchall() from an SQL query is not being read into another SQL query

there is a value I get from an SQL query which is stored with the name max_dateCS. This variable needs to be input into another SQL query. I am facing a problem doing that as it gives an error ' list index out of range'.
query2 = """select max(date_hour) from mu_test_table1"""
cur.execute(query2);
conn.commit()
max_dateCS = cur.fetchall();
Query3= """select count (*) from mu_test_table1
where date_hour = %s;"""
cur.execute(Query3,(max_dateCS[0]));
conn.commit()
rows = cur.fetchall();

SQL Query Inserting Values

I am trying to insert values into database table using Python. I have connected to the database server and have gotten the INSERT INTO sql statement to work, however I cannot figure out how to insert values from a list into my database. I think my problem is simple, and just involves using the for-in loop correctly, but I do not know how to fix it.
The line I need help with is "for i in cur:
cur.execute("INSERT INTO Events2013 VALUES (i))")"
Here is part of my code:
import cx_Oracle
import fileDb
import g
fileDb.loadTeams()
fileDb.loadEvents()
for event in g.eventList:
print '%s, %s, %s' % (event.eventName, event.eventType, event.dates)
dsn_tns = cx_Oracle.makedsn('hostname', 1521, 'orcl')
con = cx_Oracle.connect('std15', 'std15', dsn_tns)
cur = con.cursor()
for i in cur:
cur.execute("INSERT INTO Events2013 VALUES (i))")
cur.execute("SELECT * FROM Events2013")
for result in cur:
print result
cur.execute("COMMIT")
cur.close()
con.close()
cur.execute("INSERT INTO Events2013 VALUES (i))")
that i doesn't automatically expand to the variables (it's passed as a literal i)
I imagine you need something like
for event in g.eventList:
cur.execute("INSERT INTO Events2013 VALUES ('%s','%s','%s')" % (event.eventName, event.eventType, event.dates))

Categories

Resources