Insert Date into Python MySQLdb - python

I'm trying to insert the current date into MySQL using Python and its MySQLdb module. I can successfully insert the data as such:
insert = "INSERT INTO table(utdate) VALUES('2015-12-31')"
However, I don't want to hard code the date and would rather use a variable or function like:
today = time.strftime('%Y-%m-%d')
I've tried all of the following queries but without success. A successful entry into the database should appear as datetime.date(2016, 01, 01). Below each query is the error message or the resulting entry into the database.
insert = "INSERT INTO table(utdate) VALUES(today)"
_mysql_exceptions.OperationalError: (1054, "Unknown column 'today' in 'field list'")
insert = "INSERT INTO table(utdate) VALUES('today')"
(None)
insert = "INSERT INTO table(utdate) VALUES('%s')" % (today)
(None)
insert = "INSERT INTO table(utdate) VALUES(%s)" % (today)
(None)
My hunch is that the issue has to do something with the today variable since it is a string and I must use quotes to insert it. What are your thoughts and suggestions?
Thanks in advance.

Use a prepared statement and the db api will handle the type mapping for you. From the documentation at http://mysql-python.sourceforge.net/MySQLdb.html#some-examples
import MySQLdb
db=MySQLdb.connect(passwd="moonpie",db="thangs")
To perform a query, you first need a cursor, and then you can execute
queries on it:
c=db.cursor()
max_price=5
c.execute("""SELECT spam, eggs, sausage FROM breakfast
WHERE price < %s""", (max_price,))
In this example, max_price=5 Why, then, use %s in the string? Because
MySQLdb will convert it to a SQL literal value, which is the string
'5'. When it's finished, the query will actually say, "...WHERE price < 5".
Why the tuple? Because the DB API requires you to pass in any
parameters as a sequence. Due to the design of the parser, (max_price)
is interpreted as using algebraic grouping and simply as max_price and
not a tuple. Adding a comma, i.e. (max_price,) forces it to make a
tuple.

Related

Not enough arguments for format string error when inserting list into database SQL Python

I'm trying to insert a list into separate columns of a database
print inserter
params = ['%s' for item in inserter]
sql_query = 'INSERT INTO tablename (coloumn1, coloumn2, coloumn3, coloumn4, coloumn5, coloumn6, coloumn7) VALUES (%s,%s,%s,%s,%s,%s,%s);' % ','.join(params)
cursor.execute(sql_query)
db.commit
But keep getting the error
not enough arguments for format string
Anyone know what I am doing wrong?
Anyone know what I am doing wrong?
You are using string interpolation in a query.
This is bad, mainly for 2 reasons:
It is erroneous as you see. The python interpreter is confused between the %s for the interpolation and the %s for the sql parameters.
It makes your code vulnerable for sql injection.
You should use a parametrized query:
sql_query = '''INSERT INTO tablename (coloumn1, coloumn2, coloumn3,
coloumn4, coloumn5, coloumn6, coloumn7)
VALUES (%s,%s,%s,%s,%s,%s,%s);'''
cursor.execute(sql_query, inserter) # assuming inserter is a tuple/list of values

dynamic table mysqldb python string/int issue

I am receiving an error when trying to write data to a database table when using a variable for the table name that I do not get when using a static name. For some reason on the line where I insert, if I insert an integer as the column values the code runs and the table is filled, however, if I try to use a string I get a SQL syntax error
cursor = db.cursor()
cursor.execute('DROP TABLE IF EXISTS %s' %data[1])
sql ="""CREATE TABLE %s (IP TEXT, AVAILIBILITY INT)""" %data[1]
cursor.execute(sql)
for key in data[0]:
cur_ip = key.split(".")[3]
cursor.execute("""INSERT INTO %s VALUES (%s,%s)""" %(data[1],key,data[0][key]))
db.commit()
the problem is where I have %(data[1], key, data[0][key]) any ideas?
It's a little hard to analyse your problem when you don't post the actual error, and since we have to guess what your data actually is. But some general points as advise:
Using a dynamic table name is often not way DB-systems want to be used. Try thinking if the problem could be used by using a static table name and adding an additional key column to your table. Into that field you can put what you did now as a dynamic table name. This way the DB might be able to better optimize your queries, and your queries are less likely to get errors (no need to create extra tables on the fly for once, which is not a cheap thing to do. Also you would not have a need for dynamic DROP TABLE queries, which could be a security risk.
So my advice to solve your problem would be to actually work around it by trying to get rid of dynamic table names altogether.
Another problem you have is that you are using python string formatting and not parameters to the query itself. That is a security problem in itself (SQL-Injections), but also is the problem of your syntax error. When you use numbers, your expression evaluates to
INSERT INTO table_name VALUES (100, 200)
Which is valid SQL. But with strings you get
INSERT INTO table_name VALUES (Some Text, some more text)
which is not valid (since you have no quotes ' around the strings.
To get rid of your syntax problem and of the sql-injection-problem, don't add the values to the string, pass them as a list to execute():
cursor.execute("INSERT INTO table_name VALUES (%s,%s)", (key, data[0][key]))
If you must have a dynamic table name, put that in your query string first (e.g. with % formatting), and give the actual values for your query as parameters as above (since I cannot imagine that execute will accept the table name as a parameter).
To put it in some simple sample code. Right now you are trying to do it like this:
# don't do this, this won't even work!
table_name = 'some_table'
user_name = 'Peter Smith'
user_age = 47
query = "INSERT INTO %s VALUES (%s, %s)" % (table_name, user_name, user_age)
cursor.execute(query)
That creates query
INSERT INTO some_table VALUES (Peter Smith, 100)
Which cannot work, because of the unquoted string. So you needed to do:
# DON'T DO THIS, it's bad!
query = "INSERT INTO %s VALUES ('%s', %s)" % (table_name, user_name, user_age)
That's not a good idea, because you need to know where to put quotes and where not (which you will mess up at some point). Even worse, imagine a user named named Connor O'Neal. You would get a syntax error:
INSERT INTO some_table VALUES ('Connor O'Neal', 100)
(This is also the way sql-injections are used to crush your system / steal your data). So you would also need to take care of escaping the values that are strings. Getting more complicated.
Leave those problems to python and mysql, by passing the date (not the table name) as arguments to execute!
table_name = 'some_table'
user_name = 'Peter Smith'
user_age = 47
query = "INSERT INTO " + table_name + " VALUES (%s, %s)"
cursor.execute(query, (user_name, user_age))
This way you can even pass datetime objects directly. There are other ways to put the data than using %s, take a look at this examples http://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-execute.html (that is python3 used there, I don't know which you use - but except of the print statements it should work with python2 as well, I think).

Programming Error in python, How do I parse values of a tuple in a table with SQL query?

In order to parse the values of variables a and b in the field username and password respectively of table admin_details I tried this method the pseudo code is something like below:
...
...
a=4
b=8
....
....
cur.execute("INSERT INTO admin_details(username, password) VALUES('%s','%s'), %(a,b)")
....
I get the value inserted in the table as username: 4 password:8
But in order to insert the characters like** a=' john' b='snow'in the admin_details field.
I tried using tuples as below
a='john'
b='snow'
tup=['a','b']
and to insert this tuple's value a and b in the table i tried all the possible ways but still I am not able to store the variables in the table.
cur.execute("INSERT INTO admin_details(username, password) VALUES('%s','%s'), % ['a','b']")
But I get this
_mysql_exceptions.ProgrammingError: (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 'INTO INTO admin_details(username) VALUES('%s'), %('entry1.get()')' at line 1")
Do not attempt to use string formatting for constructing SQL queries. Pass query parameters in the second argument to execute() - this way you'll protect yourself against sql injection problems:
a = 'john'
b = 'snow'
cur.execute("INSERT INTO admin_details(username, password) VALUES(%s, %s)", (a, b))
Note that in this case you also don't need quotes around the placeholders in the query.
See also:
Python MySQL Parameterized Queries
I think use this way to insert mysql data should be better:
insert_sql = 'INSERT INTO admin_details(username, password) VALUES("{0}","{1}")'.format(*tup)
cur.execute(insert_sql)
conn.commit()

Inserting a CLOB using cx_Oracle

I am trying to insert a CLOB using the following code.
cursor = connection.cursor()
cursor.setinputsizes(HERP = cx_Oracle.CLOB)
cursor.execute("INSERT INTO myTable (FOO, BAR) VALUES (:FOO, :BAR)", FOO=val1, BAR=val2)
cursor.execute("INSERT INTO myTable2 (HERP) VALUES (:HERP)", HERP=val3)
#len(HERP) 39097
When I run the script WITHOUT cursor.setinputsizes(HERP = cx_Oracle.CLOB) it fails on the second query WITH ValueError: string data too large, when I run the script with cursor.setinputsizes(HERP = cx_Oracle.CLOB) it fails on the first query with DatabaseError: ORA-01036: illegal variable name/number. The CLOB I am trying to insert contains a code snippet (i.e. it has a lot of semi colons, commas and parenthesis), "string".decode("ascii") returns u'string', so unicode isn't the problem... right? I don't know if either of these things are problems. The field in the database is a currently a CLOB, however I have tried it with an NCLOB and the behavior did not change.
I have also tried the field as a BLOB and then used .encode("hex") on the value I was inserting, again same behavior.
I have also tried HERP = cursor.var(cx_Oracle.CLOB) instead of cursor.setinputsizes(HERP = cx_Oracle.CLOB), same issues.
I've been going through the discussions on the cx-oracle-users list, but no luck yet.
It works if I use this line cursor.execute("INSERT INTO myTable2 (HERP) VALUES (:HERP)", HERP="".join(set(val3)).encode("hex")), so I don't think it's an issue with the data's content (This is with the BLOB).
How can I use cx_Oracle to insert a CLOB into an Oracle database?
There are a few possible solutions:
Upgrade cx_Oracle. I'm not sure which version you're using, but I'm using python 2.7.2 with cx_Oracle 5.1 and I don't get any errors when inserting 150,000 chars into a CLOB column without using setinputsizes at all.
Since setinputsizes applies to every subsequent cursor use, just change it between these different cursor.execute statements.
eg:
cursor = connection.cursor()
cursor.setinputsizes(FOO=None, BAR=None)
cursor.execute("INSERT INTO myTable (FOO, BAR) VALUES (:FOO, :BAR)",
FOO=val1, BAR=val2)
cursor.setinputsizes(HERP = cx_Oracle.CLOB)
cursor.execute("INSERT INTO myTable2 (HERP) VALUES (:HERP)", HERP=val3)

What is the syntax to INSERT datetime variable INTO VALUES

What is the syntax for inserting a SQL datetime data type into a row?
The following in Python gives a NULL value for the timestamp variable only.
timestamp = datetime.datetime.today()
print timestamp
query = "INSERT INTO table1 (name, class, time_update) VALUES('ONE','TWO',#timestamp)"
cursor.execute(query)
I'm sure it depends on which database backend you're using, but in SQLite for example, you need to send your parameter as part of the query (that's what a parameterized statement is all about):
timestamp = datetime.datetime.today()
print timestamp
query = "INSERT INTO table1 (name, class, time_update) VALUES('ONE','TWO',?)"
cursor.execute(query, (timestamp,))
It really depends on the database. For MySQL, according to this, you can specify a timestamp/datetime in several formats, mostly based on ISO8601: 'YYYY-MM-DD', 'YY-MM-DD', 'YYYYMMDD' and 'YYMMDD' (without delimiters) or if you want greater precision 'YYYY-MM-DD HH:MM:SS' or 'YY-MM-DD HH:MM:SS' ('YYYYMMDDHHMMSS' or 'YYMMDDHHMMSS').
As far as querying goes you should probably parameterise (it's safer and a very good habit) by specifying a placeholder in the query string. For MySQL you could do:
query = "INSERT INTO table1 (name, class, time_update) VALUES('ONE','TWO',%s)"
cursor.execute(query, (timestamp,))
but the syntax for placeholders varies (depending on the db interface/driver) — see the documentation for your DB/Python interface.

Categories