I'm trying to export a table, contained within an Oracle 12c database, to csv format - using Python 2.7. The code I have written is shown below:
import os
import cx_Oracle
import csv
SQL = 'SELECT * FROM ORACLE_TABLE'
filename = 'C:\Temp\Python\Output.csv'
file = open(filename, 'w')
output = csv.writer(file, dialect='excel')
connection = cx_Oracle.connect('username/password#connection_name')
cursor = connection.cursor()
cursor.execute(SQL)
for i in cursor:
output.writerow(i)
cursor.close()
connection.close()
file.close()
This code yields an error in the line where I define 'connection':
ORA-12557: TNS:protocol adapter not loadable
How can I remedy this? Any help would be appreciated.
Please note: I have already encountered StackOverflow responses to very similar problems to this. However, they often suggest changing the path within environment variables - I cannot do this since I don't have appropriate administer privileges. Thanks again for your assistance.
ORA-12557 is caused by problems with the %ORACLE_HOME% on Windows. That's the usual suggestion is to change the PATH setting.
"I cannot do this since I don't have appropriate administer privileges."
In which case you don't have too many options. Perhaps you could navigate to the ORACLE_HOME directory and run your script from there. Otherwise look to see what other tools you have available: Oracle SQL Developer? TOAD? SQL*Plus?
We found that by navigating to config -> Oracle and editing the file 'tnsnames.ora' the problem can be solved. The tnsnames file appears as follows:
connection_name =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS= ... )
)
(CONNECT_DATA =
(SERVICE_NAME= ...)
)
)
By changing the first instance of connection_name to connection_name.WORLD, then typing
set ORACLE_HOME=
into the command line before executing the Python script, the above script now runs with no error.
I use ini-file to store DB connection parameters. Hope it helps.
self.mydsn = cx_Oracle.makedsn(self.parser.get('oracle', 'db'),self.parser.get('oracle', 'port'),self.parser.get('oracle', 'service_name'))
try:
self.connpool = cx_Oracle.SessionPool(user=self.parser.get('oracle', 'username'),password=self.parser.get('oracle', 'userpass'),dsn=self.mydsn,min=1,max=5,increment=1)
except Exception as e:
print e
You can use this python script for oracle csv export:
https://github.com/teopost/csv_exp
Related
My DB is located here:
D:\sqlite\db
My Python Code is located here:
D:\app\ZAKPRO\R20191121
Code looks this way:
import sqlite3
import os.path
conn = sqlite3.connect('D:\sqlite\db\db_name.db')
c = conn.cursor()
c.execute("INSERT INTO sts_meta (symbol) VALUES( 'tra' ) ")
Error-Message is:
OperationalError: no such table: sts_meta
Can anyone help to correct my code?
I separate DB and Code in different location: Is that fine and advisable?
I only find examples with relative path: Is the access with absolute path not the prefered one in python-sqlite-community? Why is that?
UPDATE
Now I have re-coded, but still facing the same issue:
filename = "dbname.db"
dir = "D:\sqlite\db"
dbpath = pathlib.Path(dir, filename)
sql = ("SELECT * from sts_meta")
conn = sqlite3.connect(dbpath)
c = conn.cursor()
c.execute(sql)
print(c.fetchall())
conn.commit()
This message I receive:
OperationalError: no such table: sts_meta
How to find out wheather I am connected to a database?
Regarding pathlib this is my db-path:
D:\sqlite\db\stocktimeseries.db
It's not that good to use a relative path.
Good practice would be to use path.join from os package in python.
And at any string which contains any characters like backslashes use r'your string'. Adding r before your string will state that the special characters contained in the following string is just a string and they serve no other purpose.
I'm not sure if that is what causes this issue. But if the table exists and you are having issues with path, then path.join can help you out.
This code runs perfectly fine if I first redirect to the folder where this main.py file is located. So in cmd I just type: python main.py. In this folder is also my database "Datalog.db" located.
If I run this python file from somewhere else, I get a problem with this line of code: cur.execute(sql). So in cmd I type: python C:\Users\ [...] \main.py. I get following error: "sqlite3.OperationalError: no such table: Datalog". Later I want to include this python file in a pythonshell in node-red and there I have to define the full path of this main.py
I also tried to build an exe-file with it but then the same error occurs:"sqlite3.OperationalError: no such table: Datalog".
Apparently the connection to the database is not the issue, first my cur.execute command is not working.
I find out that I have to "include my SQLite database file in the include_files statement", but I have no idea how to do this ..
Can anybody help? I am very sorry for any inconvenience, I just started programming and this is my first post.
import sqlite3 as db
db_name = 'Datalog'
output_number = 'Output1'
output = 'hello'
timestamp = '2019-11-11 09:27:02'
db_name = f'{db_name}.db'
con = db.connect(db_name)
with con:
cur = con.cursor()
sql = f"UPDATE Datalog SET {output_number}='{output}' WHERE timestamp ='{timestamp}'"
cur.execute(sql)
con.commit()
print("### DB updated ###")
You can change db_name to the full path of your sqlite database or even better, dynamically build the path to the db (Below code assumes the db is in the same folder (directory) as the file which calls the below code ):
import os.path
db_name = os.path.dirname(os.path.abspath(__filename__)) + 'Datalog'
python looks for files in "sys.path" so you want to insert the name of the directory containing your file in that path so python can find it
here is an example:
import sys
sys.path.insert(0, r'C:\Users\Philip\Work\Bin')
where 0 is the position in the sys.path, 0 means top, 1 means second from top etc.
obviously you would replace my directory with yours
I need a python script to extract a list of visted urls to a txt file for a project i'm working on.
I have tried sevral codes I found online and none of them seem to work for me.
(java is also fine although python is preferred.)
Thanks.
You can use the sqlite3 module to read the Chrome history file.
import sqlite3
history_db = 'C:\\Users\\USERID\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\History'
c = sqlite3.connect(history_db)
cursor = c.cursor()
select_statement = "SELECT urls.url, urls.visit_count FROM urls, visits WHERE urls.id = visits.url;"
cursor.execute(select_statement)
results = cursor.fetchall()
with open('PATH_TO_TXT\\history.txt', 'a') as file:
for i in results:
file.write("{0} - {1}\n".format(i[0], i[1]))
More info
I am creating a plugin for QGIS (QGIS Plugin Builder). The relative paths to the plugin directory need to start with a colon. The icon for example is loaded like this:
icon_path = ':/plugins/into_sqlite/icon.png'
When I try to do the same for the sqlite database the database fails to load:
connection = sqlite3.connect(":/plugins/PLUGINNAME/database.sqlite")
OperationalError: unable to open database file
But when I try the same giving the absolute path it works:
connection = sqlite3.connect("/home/USERNAME/.qgis/python/plugins/PLUGINNAME/database.sqlite")
OperationalError: unable to open database file
I think that the problem is that the path starts with a colon and sqlite uses the colon as a special character to for example load a database in memore:
connection = sqlite3.connect(":memory:")
But I need to use realtive paths. How can I supply the path and escape the colon or start the path without the colon?
I now went around the problem by using this code:
path = abspath(":/plugins/PLUGINNAME/")
path_abs = path.replace(":", ".qgis2/python")
path_db = join(path_abs, "db.sqlite")
connection = sqlite3.connect(path_db)
The variables have these values:
path = "/home/USERNAME/:/plugins/PLUGINNAME"
path_abs = "/home/USERNAME/.qgis2/python/plugins/PLUGINNAME"
path_db = "/home/USERNAME/.qgis2/python/plugins/PLUGINNAME/db.sqlite"
Another suggestion:
On IRC the suggestion was:
curr_path = os.path.dirname(os.path.abspath(__file__))
self.path_db = os.path.join(curr_path, 'db.sqlite')
I want to create an Access database (*.accdb) from within a Python script.
Using win32com and Dispatch I can call the application. However, I cant find anything on how to create a new database.
access = win32com.client.Dispatch('Access.Application')
At that point I have no need to put data into the database and I would do this using pyodbc - I simply need to create an empty database.
Does somebody has an example on how to do this?
Cheers Thomas
You have an Access application object. Use its DBEngine.CreateDatabase method to create your db file.
This sample worked from Python 2.7 to create an MDB format database file. To create an ACCDB, use 128 (dbVersion120) for dbVersion.
import win32com.client
oAccess = win32com.client.Dispatch('Access.Application')
DbFile = r'C:\Users\hans\Documents\NewDb.mdb'
dbLangGeneral = ';LANGID=0x0409;CP=1252;COUNTRY=0'
# dbVersion40 64
dbVersion = 64
oAccess.DBEngine.CreateDatabase(DbFile, dbLangGeneral, dbVersion)
oAccess.Quit()
del oAccess
To create a new, empty .accdb file, the following Python code should do the trick:
import win32com.client
f = 'C:\\Users\\Gord\\Desktop\\pyTest.accdb'
c = win32com.client.Dispatch('ADOX.Catalog')
c.Create('Provider=Microsoft.ACE.OLEDB.12.0;Data Source=' + f + ';')
c = None
print '"' + f + '" created.'
[Edit 1]
A comment to a blog posting here suggests that if the .Create call generates a "Class not registered" error you may need to use regsvr32.exe to re-register msadox.dll. Be aware of "bitness" when you attempt this: There are 32-bit and 64-bit versions of both of those files:
64-bit
C:\Windows\System32\regsvr32.exe
C:\Program Files\Common Files\System\ado\msadox.dll
32-bit
C:\Windows\SysWOW64\regsvr32.exe
C:\Program Files (x86)\Common Files\System\ado\msadox.dll
Also, be aware that you could be running 32-bit Python on a 64-bit machine.
[Edit 2]
I've done a few tests and have reached the conclusion that this approach did not work in this particular case because the Python script was running as 64-bit, but the 64-bit Access Database Engine was not installed. (32-bit Office only installs the 32-bit version of ACE.)
The error message was perhaps a bit misleading. It wasn't the ADOX component that was missing (not registered), it was the 64-bit version of the ACE engine itself that couldn't be found.
Furthermore, on a 64-bit machine with 32-bit Access installed, the 64-bit version of ACE will never be available because it cannot be installed
This could very well have implications when you try to manipulate data within the .accdb file from a 64-bit Python script. I didn't have Python available on my "32-bit Office on 64-bit Windows" test machine, but when I tried the following VBScript...
Option Explicit
Dim con, rst
Set con = CreateObject("ADODB.Connection")
con.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data source=C:\Users\Gord\Desktop\adoTest.accdb;"
Set rst = CreateObject("ADODB.Recordset")
rst.Open "SELECT Field1 FROM Table1", con
Wscript.Echo rst(0).Value
rst.Close
Set rst = Nothing
con.Close
Set con = Nothing
...the results were as follows:
C:\__tmp>C:\Windows\System32\cscript.exe /nologo dataAccessTest.vbs
C:\__tmp\dataAccessTest.vbs(4, 1) ADODB.Connection: Provider cannot be found.
It may not be properly installed.
C:\__tmp>C:\Windows\SysWOW64\cscript.exe /nologo dataAccessTest.vbs
This is Table1 data in Access.
The script failed when run as 64-bit, but it worked when run as 32-bit.
Recommendation: If your machine has 32-bit Access installed you'll probably be better off running your Python scripts as 32-bit too.
import win32com.client
ConFileName = r'c:\mydb\myaccess.mdb'
try:
Catalog = win32com.client.Dispatch('ADOX.Catalog')
Catalog.Create('Provider=Microsoft.ACE.OLEDB.12.0;Data Source=' + ConFileName + ';')
Catalog = None
except:
Exception as e:
print("Database generation failed, Error="+str(e))
print("NewAccessDB.mdb created successfully")
Then you can connect to access database :
ConFileName=(r'c:\mydb\myaccess.mdb')
conn = pyodbc.connect(r'Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=' + ConFileName + ';')
cursor = conn.cursor()
To insert in to the access table :
ConFileName=(r'c:\mydb\myaccess.mdb')
conn = pyodbc.connect(r'Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=' +ConFileName+ ';')
cursor = conn.cursor()
for ta in TableArray:
Sql_insert_query = "INSERT INTO Table1(ID, Value1,Value2,Value3,Value4,Value5,Value6) " \
"VALUES ('{a}','{b}','{c}','{d}','{e}','{f}','{g}')".format(a=str(ta[0]),b=str(ta[1]),c=str(ta[2]),d=str(ta[3]),e=str(ta[4]),f=str(ta[5]),g=str(ta[6]))
cursor.execute(Sql_insert_query)
conn.commit()
cursor.close()
Please follow this link for more information :
https://elvand.com/python-and-ms-access/