I've been having this issue for some time now and here is the short story:
I want to edit a date in my Sqlite database with a Python script so I do this using:
import sqlite3
db = sqlite3.connect('test.db')
cursor = db.cursor()
cursor.execute("UPDATE info SET date = '2003-03-14 12:34:20' WHERE id = 10")
but when I execute this I get an exception:
sqlite3.OperationalError: no such module: fts4
with some troubleshooting I've managed to narrow it down to having some issues with the quote marks. Since even if I just reduce it to a single year it still produces an exception.
The same exception appear if I try to insert a string using quote marks.
How can I fix this? Most solutions I find is solved though enabling fts3/fts4 with the SQLITE_ENABLE_FTS3 flag when building, but I have no idea of how to do that.
Besides, the exact same code runs smoothly both in Python 3.6.5 and 2.7.12. what happened in Python3?, or more specifically 3.5.2.
I should add, that it works in linux but not in windows.
Related
I am using psycopg2 library and iI made a query to select instances from a table in a database. I have run the code in a user interface program and it works however, I get an error when I run it in python. Here is the code:
find_id = 'SELECT "serial_number" FROM "LogFiles" WHERE "LogFiles"."user_name" = my product;'
cur.execute(find_id)
cur.fetchall()
ERROR happen in ^:
find_id='SELECT "serial_number" FROM "LogFiles" WHERE
"LogFiles"."user_name" = my ^product ;'
It seems that I need to deal with the space inside of a string as reading of the instance is stopped after my.
I have tried to use "my product" and '''my product''' and ''my product'' but they don't work as well.
I am trying to select data from an ORACLE 12c database using cx_Oracle, but I am getting the exception: "cx_Oracle.OperationalError: ORA-03113: end-of-file on communication channel".
My query behaves fine using Pycharm (jdbc:oracle:thin driver). Using cx_Oracle in python 3.6, however, the query fails unless I reduce the number of IDs in the IN clause from 500 to about 250. The Cursor.fetchall() function is what throws the exception. I do not have privileged access to the database in order to check things like locks or load, but could these be the cause of the issue? According to our DBA, there is nothing wrong on the Oracle db server, and since the query works fine otherwise, I am inclined to believe it. I have messed with the client-side sqlnet.ora as well, which has allowed exceptions to eventually be thrown instead of hanging forever, but I still cannot fetch the data.
def select(self, query, *args):
cur = self.dbh.cursor()
cur.prepare(query)
try:
cur.execute(None, args)
return cur.fetchall()
# my attempt to handle the issue
except (cx_Oracle.OperationalError, cx_Oracle.DatabaseError) as e:
# cx_Oracle.OperationalError: ORA-03113: end-of-file on communication channel
self.logger.error('Oracle Error: {}'.format(traceback.format_exc()))
raise e
The code calls select like this. For brevity, I've omitted the full string IDs
ids = ['1', '2', '3', ...]
query = """\
select * from my_table where id in(:0,:1,:2,:3,:4, ...)
"""
self.select(query, *ids)
The query fails without the placeholders (with the IDs placed directly in the query) as well.
I expect to be able to run any select query using an IN clause with up to 1000 IDs without receiving the ORA-03113 Exception.
Edit:
I installed oracle-instantclient18.5-basic-18.5.0.0.0-3.x86_64.rpm* on ubuntu 18.04.2, have cx_Oracle version 7.1.2, and I am connecting to Oracle 12.1.0.2.0.
The query is on the underlying tables of BMC Software's ARS. I will start working to try to replicate the problem with a local table structure, but it is a mess and will take some time. If I am able to create a local copy of the tables, I'm not sure I'd be able to replicate the issue, as identical queries with different IDs work fine. That makes it seem data driven, however, after I reduced the query to 250 IDs, I swapped the 250 from the first half to the second half, and got the same success result, so it doesn't seem to be just one bad row.
Is there more helpful logging I can enable on the client side to get more information?
Edit2: I should also add that the issue does not just occur with one query. I've seen the same issue with select queries to completely different tables.
Edit3: I just found out that by commenting out some of the columns that I'm selecting also can make the query work. columns like this:
to_char(to_date('1970-01-01','YYYY-MM-DD') + numtodsinterval(EventStart,'SECOND'),'YYYY-MM-DD HH24:MI:SS')
This may indicate that some kind of timeout is being reached which may or may not be configured in my sqlnet.ora:
DISABLE_OOB=on
SQLNET.RECV_TIMEOUT=60
SQLNET.SEND_TIMEOUT=60
TCP.CONNECT_TIMEOUT=300
SQLNET.OUTBOUND_CONNECT_TIMEOUT=300
ENABLE=BROKEN
TRACE_LEVEL_CLIENT=ADMIN
TRACE_FILE_CLIENT=sqlnet
Edit 4: I've tried some more things.
I installed the same version of instant client, except on a windows 7 machine, and ran the same query against the same db instance. The query succeeded.
I also narrowed down that for this particular query, it will accept 499 IDs, but fails with 500. it doesn't matter which ID I comment out from the query.
I also tried tricking the query into thinking there were fewer IDs by using a sub-select instead:
IN(
select regexp_substr(:0,'[^,]+', 1, level) from dual connect by regexp_substr(:0, '[^,]+', 1, level) is not null
)
I got the error "cx_Oracle.DatabaseError: ORA-01460: unimplemented or unreasonable conversion requested", after which I realized made sense because Oracle will only allow a string to be up to 4000 bytes long.
I think I finally found a way to get everything functioning. I finally came across this link:
https://ardentperf.com/2010/09/08/mysterious-oracle-net-errors/
It turns out that this solved my problem. I am still having trouble getting cx_Oracle to honor a connection string of the same format as the tnsnames.ora file, but I changed my code to refer to the tnsnames.ora for now as follows:
connection_info = {
'user': self.config.get(self.db, 'user'),
'pass': self.config.get(self.db, 'password')
}
connection_string = '{user}/{pass}#TEST'\
.format(**connection_info)
connection = cx_Oracle.connect(connection_string)
where my tnsnames.ora contains the following:
TEST =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(Host = myhost.com)(Port = 1521))
)
(SDU=1024)
(CONNECT_DATA =
(SID=mysid)
)
)
The key here is the SDU=1024, which inexplicably fixes this issue.
https://docs.oracle.com/cd/B28359_01/network.111/b28317/sqlnet.htm#NETRF184
Documentation from the above link indicates that the default for SDU is 8192 bytes (8 KB) and my understanding is that there is supposed to be auto-negotiation of this value. This does not appear to be the case, and I don't know what past defaults have been.
Importing the SQLite3 module works at first, and creating a database or table works fine too.
But suddenly, when trying to insert something in it — Python throws an irresponsible kind of error (sometimes throws syntaxError without highlighting any line of code — seriously, there's no reason for the error).
I know SQLite3 on Android 6.0 raises issues — there are many options to solve this on Java but is there any solution for QPython (Android 6.0)?
This is my insert line:
c.execute("INSERT INTO pins(pin) VALUES (?)", (S)
The above is the line python points the error to
Close the cur.execute properly
There is this thing with python tuples, so add a comma to the data tuple
cur.execute("INSERT INTO pins(pin) VALUES (?)", (S,))
I've browsed some of the other questions about MySQL and Python on SO. There are a few things eluding me, because I'm pretty new to Python.
First, I'm trying to get a simple guestbook app to work. It takes posted variables and puts them into a MySQL database. Take a look:
con = MySQLdb.connect (host = "localhost",
user = "Chat",
passwd = "myPass",
db = "Chatserver")
cursor = con.cursor()
cursor.execute ("INSERT INTO guestbook (name,message) VALUES(%s,%s)",(name,greeting))
Ok, so some of the tutorials and answers on SO have many Quotation marks surrounding the SQL query, and I don't know why that is. I've tried it with 1 quote, I've tried it with 3 quotes, and it just never works. There are no exception callbacks and the code seems to run, but no records are ever entered into the database.
So my two questions are, how many quotation marks do I need when encapsulating the Queries, and why doesn't my script add anything to the database but not report any errors?
Ok, this answer Can't execute an INSERT statement in a Python script via MySQLdb helped me figure it out.
You have to add this at the end of your query.
cursor.execute(...)
con.commit() //this is what makes it actually do the execution?
Question: Why is this sqlite3 statement not updating the record?
Info:
cur.execute('UPDATE workunits SET Completed=1 AND Returns=(?) WHERE PID=(?) AND Args=(?)',(pickle.dumps(Ret),PID,Args))
I'm using python and sqlite3. this statement does not throw an error, it just seems like it is out right ignored. for testing reasons I included below it:
cur.execute('SELECT * FROM workunits WHERE PID=(?) AND Args=(?)',(PID,Args))
Which returns a record just fine. but the record doesn't up date with the new value of the pickled ret. it remains u''. I can't figure out why. my where statement seems to work. my syntax seems to be correct because there is no error being thrown. I'm clueless as to why exactly it doesn't work.
If the problem persists after you fixed your syntax. Please make sure you're using:
conn.commit()
After cur.execute, UPDATES and INSERTS require COMMIT.
don't use 'AND', use a ','.
cur.execute('UPDATE workunits SET Completed=1, Returns=? WHERE PID=? AND Args=?',
(pickle.dumps(Ret), PID, Args)
)