I'm trying to update TIMESTAMP column in table with None value in python code.
It worked perfectly when using insert statement with null value.
But when using update statement, it doesn't work!!
following is test code for your understanding.
(The reason why I'm updating 'None' value is that the new value is from the other database, and I want to update the value with the new one, and some of the values are NULL.)
:1 is '20160418154000' type string in python code
but when it is 'None' value it raise exception.
INSERT INTO TEST_TABLE (ARR_TIME) VALUES(TO_TIMESTAMP(:1, 'YYYYMMDDHH24MISS'))
it works well!!
UPDATE TEST_TABLE SET ARR_TIME = TO_TIMESTAMP(:1, 'YYYYMMDDHH24MISS')
it doesn't work!!
error message : ORA-00932: inconsistent datatypes: expected - got NUMBER
I think cx_Oracle recognize the None value in python as number (0??)
and it cannot be converted to 'YYYYMMDDHH24MISS' string type.
Is there way to update NULL value in TIMESTAMP column?
Yes, there is. Unless you specify otherwise, nulls are bound as type string. You can override this, though, using the following code:
cursor.setinputsizes(cx_Oracle.TIMESTAMP)
See here for documentation:
http://cx-oracle.readthedocs.org/en/latest/cursor.html#Cursor.setinputsizes
NOTE: you could have also solved this by using this code instead:
update test_table set arr_time = :1
There is no need to convert the data using to_timestamp() as cx_Oracle can bind timestamp values directly (use datetime.datetime) and if you bind None Oracle will implicitly convert for you.
Related
I have values in few different variables and one of them stores date. When I checked data type in Python it shows Str. I added Convert(datetime,'{}',102) in my Insert statement to Insert this field in Database table since this field datatype in table is Date. This works fine when this variable has data.
Now, for some records this field is blank so Python variable holds None. How do I handle this? I want to insert NULL in this scenario.
Note-> I have this code inside for loop so I am inserting records one by one. This is why for some iterations variable might have actual date value and for some it might have None.
Current Code->
"Insert into table (col1,col2,col3) values ('{}',Convert(datetime,'{}',102),'{}')".format(var1,var2,var3)
**What I am trying to do**
I have been trying to insert a record to a table via tkinter, and I want to see the inserted record on mysql.
Issue
After entering a record to tkinter, I received the following error. I looked into the solutions for the same errors posted online, but it was to use auto_increment for column Code (the one with primary key). However, I cannot use auto_increment since the values of the column Code does not always increase. I have also tried deleting primary key for the column but I still got the same error. Any insights on this?
**Error:**
*mysql.connector.errors.IntegrityError: 1062 (23000): Duplicate entry '0' for key 'PRIMARY'*
**Code to create the table:**
#table
cursor=mycon.cursor(buffered=True)
cursor.execute("use iv")
cursor.execute("drop table if exists salesperson")
create_table='''create table salesperson
(
code int(4) primary key,
name varchar(15),
salary int,
itcode char
)'''
cursor.execute(create_table)
**Code to insert data to mysql from tkinter/python:**
from tkinter import *
from tkinter.messagebox import showinfo
def add_data():
code=tcode.get('1.0',END) #retrieve input
name=tname.get('1.0',END)
salary=tsal.get('1.0',END)
itcode=titcode.get('1.0',END)
#DATABASE CONNECTION
if code=="" or name=="" or salary=="" or itcode=="":
messagbox.showinfo("Please fill all the fields")
else:
import mysql.connector as sqltor
connection=sqltor.connect(host="localhost",user="root",password=" ",database="iv")
tkcursor=connection.cursor()
tkcursor.execute("Insert into salesperson values (code,'name',salary,'itcode')")
connection.commit()
messagebox.showinfo("Records inserted")
tkcursor.close()
The problem is in the INSERT statement:
tkcursor.execute("Insert into salesperson values (code,'name',salary,'itcode')")
When you reference an identifier in an SQL statement like this, it's an SQL identifier, not a Python variable. It's not an error in this case because your table coincidentally has columns named code and salary.
But what is the value of these columns? Since this is an INSERT statement, by definition the row doesn't exist yet as the VALUES() clause is evaluated. So the value of all columns of that row is NULL. It's exactly as if you had done this:
tkcursor.execute("Insert into salesperson values (NULL,'name',NULL,'itcode')")
Since code is the primary key, it must be NOT NULL. Even though the column does not have a DEFAULT defined, MySQL has a concept of a "default default." That is, in absence of an explicitly defined default value, each data type will be converted to an appropriate implicit default value if NULL is not accepted (see https://dev.mysql.com/doc/refman/8.0/en/data-type-defaults.html for documentation on this). For an integer, the implicit default is 0. So your statement works as if you did this:
tkcursor.execute("Insert into salesperson values (0,'name',NULL,'itcode')")
How to fix this? You should use parameters to help you get the values of your Python variables into your SQL INSERT statement. That way the Python variable code will be used, not the SQL column that is also named code. The comment above from nbk hinted at this.
tkcursor=connection.cursor(prepared=True)
tkcursor.execute("Insert into salesperson values (%s,'name',%s,'itcode')", (code, salary,)
connection.commit()
See https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursorprepared.html for more information.
I have a python script which selects some rows from a table and insert them into another table. One field has type of date and there is a problem with its data when its value is '0000-00-00'. python converts this value to None and so gives an error while inserting it into the second table.
How can I solve this problem? Why python converts that value to None?
Thank you in advance.
This is actually a None value in the data base, in a way. MySQL treats '0000-00-00' specially.
From MySQL documentation:
MySQL permits you to store a “zero” value of '0000-00-00' as a “dummy
date.” This is in some cases more convenient than using NULL values,
and uses less data and index space. To disallow '0000-00-00', enable
the NO_ZERO_DATE mode.
It seems that Python's MySQL library is trying to be nice to you and converts this to None.
When writing, it cannot guess that you wanted '0000-00-00' and uses NULL instead. You should convert it yourself. For example, this might work:
if value_read_from_one_table is not None:
value_written_to_the_other_table = value_read_from_one_table
else:
value_written_to_the_other_table = '0000-00-00'
I have a dictionary of column name / values, to insert into a table. I have a function that generates the INSERT statement. I'm stuck because the function always puts quotes around the values, and some are integers.
e.g. If column 1 is type integer then the statement should be INSERT INTO myTable (col1) VALUES 5; vs
INSERT INTO myTable (col1) VALUES '5'; second one causes an error saying column 5 does not exist.
EDIT: I found the problem (I think). the value was in double quotes not single, so it was "5".
In Python, given a table and column name, how can I test if the INSERT statement needs to have '' around the VALUES ?
This question was tagged with "psycopg2" -- you can prepare the statement using a format string and have psycopg2 infer types for you in many cases.
cur.execute('INSERT INTO myTable (col1, col2) VALUES (%s, %s);', (5, 'abc'))
psycopg2 will deal with it for you, because Python knows that 5 is an integer and 'abc' is a string.
http://initd.org/psycopg/docs/usage.html#passing-parameters-to-sql-queries
You certainly want to use a library function to decide whether or not to quote values you insert. If you are inserting anything input by a user, writing your own quoting function can lead to SQL Injection attacks.
It appears from your tags that you're using psycopg2 - I've found another response that may be able to answer your question, since I'm not familiar with that library. The main gist seems to be that you should use
cursor.execute("query with params %s %s", ("param1", "pa'ram2"))
Which will automatically handle any quoting needed for param1 and param2.
Although I personally don't like the idea, you can use single quotes around integers when you insert in Postgres.
Perhaps your problem is the lack of parentheses:
INSERT INTO myTable(col1)
VALUES('5');
Here is a SQL Fiddle illustrating this code.
As you note in the comments, double quotes do not work in Postgres.
You can put always the single quote (be careful, if the value contents a quote you must double it: insert into example (value_t) values ('O''Hara');
You can decide checking the value that you want to insert regardles of the type of de destination
You can decide checking the type of the target field
As you can see in http://sqlfiddle.com/#!15/8bfbd/3 theres no mater with inserting integers into a text field or string that represents an integer in a numeric field.
To check the field type you can use the information_schema:
select data_type from information_schema.columns
where table_schema='public'
and table_name='example'
and column_name='value_i';
http://sqlfiddle.com/#!15/8bfbd/7
python 2.7
pyramid 1.3a4
sqlalchemy 7.3
sqlite3.7.9
from sqlite prompt > I can do:
insert into risk(travel_dt) values ('')
also
insert into risk(travel_dt) values(Null)
Both result in a new row with a null value for risk.travel_dt but when I try those travel_dt values from pyramid, Sqlalchemy gives me an error.
In the first case, I get sqlalchemy.exc.StatementError:
SQLite Date type only accepts python date objects as input
In the second case, I get Null is not defined. When I use "Null", I get the first case error
I apologize for another question on nulls: I have read a lot of material but must have missed something simple. Thanks for any help
Clemens Herschel
While you didn't provide any insight into the table definition you're using or any example code, I am guessing the issue is due to confusing NULL (the database reserved word) and None (the Python reserved word).
The error message is telling you that you need to call your SQLA methods with valid python date objects, rather than strings such as "Null" or ''.
Assuming you have a Table called risk containing a Column called travel_dt, you should be able to create a row in that table with something sort of like:
risk.insert().values(travel_dt=None)
Note that this is just a snippet, you would need to execute such a call within an engine context like that defined in the SA Docs SQL Expression Language Tutorial.