File not being released - python

Ok so I have to run some queries in access 07 then compact and repair it. I am using python and win32com to do this. The code I'm currently using is this.
import os;
import win32com.client;
DB1 = 'db1.mdb'
DB2 = 'db1N.mdb'
DB3 = 'db2.mdb'
DBR = r'db1.mdb'
access = win32com.client.Dispatch("Access.Application")
access.OpenCurrentDatabase(DBR)
DB = access.CurrentDb()
access.DoCmd.OpenQuery("1")
access.DoCmd.OpenQuery("2")
access.DoCmd.OpenQuery("3")
access.CloseCurrentDatabase()
access.Application.Quit();
os.system('copy "db1.mdb" "db2.mdb"')
access = win32com.client.Dispatch("Access.Application")
access.CompactRepair(DB3,DB2)
access.Application.Quit();
os.remove("db2.mdb")
os.remove("db1.mdb")
os.rename("db1N.mdb","db1.mdb")
The problem is that I get this error.
WindowsError: [Error 32] The process cannot access the file because it is being used by another process: 'db1.mdb'
I dont know why I am getting this error seeing as I am quiting access which should close the file. Any Idea how to fix this would be greatly appreciated.

Your code includes this line:
DB = access.CurrentDb()
When that line executes, CurrentDb() references db1.mdb. Then you later get WindowsError at:
os.remove("db1.mdb")
So I'm wondering if the variable DB still holds a reference to db1.mdb. Perhaps you could first try del DB before os.remove().
Or, since your code isn't actually using that DB variable, just get rid of it.

I made some changes to get your example to work for me. To solve your problem add DB.Close();
import os;
import win32com.client;
path='C:/project/714239'
os.chdir(path)
DB1 = 'db1.mdb'
DB2 = 'db1N.mdb'
DB3 = 'db2.mdb'
access = win32com.client.Dispatch("Access.Application")
access.OpenCurrentDatabase(path + '/' + DB1, False)
DB = access.CurrentDb()
DB.Close(); #ADDED THIS
access.CloseCurrentDatabase()
access.Application.Quit();
os.system('copy ' + DB1 + ' ' + DB2)
access = win32com.client.Dispatch("Access.Application")
access.CompactRepair(path + '/' + DB2, path + '/' + DB3, True)
access.Application.Quit();
os.remove(DB2)
os.remove(DB1)
os.rename(DB3,DB1)

Related

Getting empty list when trying to retrieve the user information from Active Directory using ldap3

I am trying to retrieve information about a user stored in Active Directory using Python ldap3.
Below is the code snippet:
ad_server = 'xx.xx.xxx.x:389'
ad_username = domain + '\\' + user_name.strip()
server = Server(ad_server,get_info=ALL)
conn = Connection(server, user=ad_username, password=ad_pwd, authentication=NTLM)
if conn.bind():
e = conn.entries('dc=ad_username,dc=example,dc=com','(objectclass=person)',attributes=['*'])
print(e) ----#empty list
The above code is not throwing any error. But I am getting an empty list for e.
Not able to figure out what I am missing here.

How to hide SQL Plus password in Python script

I created Python script which truncate Oracle table. I use SQL Plus, but the problem is that I have to hide password which is plain text now. I have arguments like these:
db_name = "DB_NAME"
db_user = "DB_USER"
db_password = "DB_PASS"
Then I run command like:
sqlplus_delete_table = 'echo "TRUNCATE TABLE ' + db_user + '.' + table + ' DROP STORAGE;"'
sqlplus_connection = db_user + '/' + db_password + '#' + db_name
os.system(sqlplus_delete_table + ' | sqlplus -s ' + sqlplus_connection)
Everything works fine, but the problem is password. As I know, SQL Plus does not use jceks files. So what are other solutions to hide password?
You can use a solution like Django's SECRET_KEY, which I store in a file that is not in the project repository. From this file I load the keys like this in settings.py:
with open(os.path.join(ROOT_DIR, 'etc/secret_key.txt')) as f:
SECRET_KEY = f.read().strip()
In the above example the contents of the text file is just the key, but you can use structured formats such as JSON, YAML, or even a Python file and import it.
Example of Python secret file:
# secret.py
DB_PSSWD='pswd'
DB_USER='user'
In your source code simply:
import secret
print(DB_USER)
Example of YAML secret file:
# secret.yaml
db_psswd: pswd
db_user: user
In your source code simply:
import yaml
with open('secret.yaml') as yaml_secret:
rules = yaml.load(cfg)
print(rules['db_user'])
On Linux it's possible to create bash-script like:
# sql.env
export db_PSSWD='pswd'
export db_USER='user'
Before running python, run bash-script to initialize environment variables:
source sql.env
Then, in python:
db_psswd = os.environ.get("db_PSSWD")
db_user = os.environ.get("db_USER")

Concatenating strings in Python

How can I properly concatenate a variable inside an string in Python?
I am trying to pass service in "Database Connections\\'service'.sde" and (r"C:\GIS\Maps\'.+service+.'.mxd")
service ="Electric"
sde = "Database Connections\\'service'.sde"
mxd = arcpy.mapping.MapDocument(r"C:\GIS\Maps\'.+service+.'.mxd")
so the output looks like
sde = "Database Connections\\Electric.sde"
mxd = arcpy.mapping.MapDocument(r"C:\GIS\Maps\Electric.mxd")
I think a better way to do this is using os.path.join:
import os
mxd = arcpy.mapping.MapDocument(os.path.join(*"C:\\GIS\\Maps\\".split('\\')
+ ["{}.mxd".format(service)]))
Also, note that your back-slashes need to be escaped.
This is how Python's string concatenation works:
sde = "Database Connections\\" + service + ".sde"
mxd = arcpy.mapping.MapDocument("C:\\GIS\\Maps\\" + service + ".mxd")
An alternative which bypasses the issue of raw strings can't end with a single backslash:
r'C:\GIS\Maps\%s.mxd' % service
and
r'C:\GIS\Maps\{}.mxd'.format(service)
both work fine, dodging the issue with the string ending in a backslash.

Export data from Oracle Database 12c using Python 2.7

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

Can one use, or how to avoid using, a colon (":") as the start of a path to an sqlite database

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')

Categories