I'm new to Python. Only been coding a month. I am stumped. The below code works perfectly until I move it to a function. I'm not at work so I can't remember the exact error, but it was something about no temp registry access. The exact error is not important since the code is working. What I can't figure out is why I can't call this code from a function. I can import this code with 'from filename.py import *' and it works.
Can an experienced Python coder explain why the access connection will not work in a function call?
import pypyodbc
gage_list = []
gage=0
ser_num=1
owner=2
duedate=3
status=4
#create connection
DBfile = "C:/ProgramData/CyberMetrics Corporation/GAGEtrak 7.0/AppFiles/Gtw70.accdb"
conn = pypyodbc.connect('DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ='+DBfile)
cursor = conn.cursor()
cursor.execute("SELECT Gage_ID FROM Gage_Master")
Gage_ID=cursor.fetchall()
cursor.execute("SELECT Gage_SN FROM Gage_Master")
Gage_SN=cursor.fetchall()
cursor.execute("SELECT GM_Owner FROM Gage_Master")
GM_Owner=cursor.fetchall()
cursor.execute("SELECT Next_Due_Date FROM Gage_Master")
Next_Due_Date=cursor.fetchall()
cursor.execute("SELECT Status FROM Gage_Master")
Status=cursor.fetchall()
conn.close()
counter = 0
for i in range(len(Gage_ID)): #combines gage columns into an array
tup = Gage_ID[i][0], Gage_SN[i][0], GM_Owner[i][0], Next_Due_Date[i][0], Status[i][0]
gage_list.append(tup)
print(gage_list[14][duedate]) #to choose a field, select from gage, ser_num, owner, duedate, or status variables
Related
I'm using this simple script, however, the for loop never executes. The script is terminated without any error - but the data is in the database. 2 weeks ago this script worked fine.
Does anyone know where the problem may be?
Thank you.
import pyodbc
conn = pyodbc.connect(r'Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=S:\Chat_OV_UL\O2Spokojenost\DtbO2Spokojenost.accdb;', autocommit=True)
cursor = conn.cursor()
cursor.execute('select * from t_prepair')
print ("Databáze načtena")
limita = 0
for row in cursor.fetchall():
limita = limita + 1
print(row[0])
print(limita)
print("----")
I tried inserting the values into the DB through python. However i do not get any error but i do not see it updating in DB. Please advice.
#!/usr/bin/python
import MySQLdb
val = MySQLdb.connect(host='localhost', user='root', passwd='root123',
db='expenses')
def access_db(val):
access = val.cursor()
sql = """Insert into monthly values (2,'Food',1000)"""
access.execute(sql)
val.commit()
val.close()
Output from DB after the script execution:
MariaDB[expenses]> select * from monthly;
SL_no Type Amount
1 Fuel 500
I do not find the second entry in Db.
I dont think you are calling the access_db() function anywhere
So, after coding with pyodbc for a couple days now, I've run into a road block it seems. My SQL update will not work, even after putting autocommit=True in the connection statement. Nothing changes in the database at all. All my code is provided below. Please help. (I am using the 2016 version of MS Access, code runs with no errors, 32 bit Python and Access.)
import pyodbc
# Connect to the Microsoft Access Database
conn_str = (
r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};'
r'DBQ=C:\Users\User_Name\Desktop\Databse\CPLM.accdb'
)
cnxn = pyodbc.connect(conn_str, autocommit=True)
crsr = cnxn.cursor()
crsr2 = cnxn.cursor()
# SQL code used for the for statement
SQL = "SELECT NameProject, Type, Date, Amount, ID FROM InvoiceData WHERE Type=? OR Type=? OR Type IS NULL AND ID > ?"
# Defining variables
date = ""
projectNumber = 12.04
numberDate = []
# Main Code, for each row in the SQL query, update the table
for row in crsr.execute(SQL, "Invoice", "Deposit", "1"):
print (projectNumber)
if row.NameProject is not None:
crsr2.execute("UPDATE Cimt SET LastInvoice='%s' WHERE Num='%s'" % (date, projectNumber))
cnxn.commit()
# Just used to find where to input certain data.
# I also know all the code in this if statement completes due to outside testing
projectNumber = row.NameProject[:5]
numberDate.append([projectNumber, date])
else:
date = row.Date
print(numberDate)
crsr.commit()
cnxn.commit()
cnxn.close()
In Python mysqldb I could declare a cursor as a dictionary cursor like this:
cursor = db.cursor(MySQLdb.cursors.DictCursor)
This would enable me to reference columns in the cursor loop by name like this:
for row in cursor: # Using the cursor as iterator
city = row["city"]
state = row["state"]
Is it possible to create a dictionary cursor using this MySQL connector?
http://dev.mysql.com/doc/connector-python/en/connector-python-example-cursor-select.html
Their example only returns a tuple.
I imagine the creators of MySQL would eventually do this for us?
According to this article it is available by passing in 'dictionary=True' to the cursor constructor:
http://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursordict.html
so I tried:
cnx = mysql.connector.connect(database='bananas')
cursor = cnx.cursor(dictionary=True)
and got:
TypeError: cursor() got an unexpected keyword argument 'dictionary'
and I tried:
cnx = mysql.connector.connect(database='bananas')
cursor = cnx.cursor(named_tuple=True)
and got:
TypeError: cursor() got an unexpected keyword argument 'named_tuple'
and I tried this one too: cursor = MySQLCursorDict(cnx)
but to no avail. Clearly I'm on the wrong version here and I suspect we just have to be patient as the document at http://downloads.mysql.com/docs/connector-python-relnotes-en.a4.pdf suggests these new features are in alpha phase at point of writing.
A possible solution involves subclassing the MySQLCursor class like this:
class MySQLCursorDict(mysql.connector.cursor.MySQLCursor):
def _row_to_python(self, rowdata, desc=None):
row = super(MySQLCursorDict, self)._row_to_python(rowdata, desc)
if row:
return dict(zip(self.column_names, row))
return None
db = mysql.connector.connect(user='root', database='test')
cursor = db.cursor(cursor_class=MySQLCursorDict)
Now the _row_to_python() method returns a dictionary instead of a tuple.
I found this on the mysql forum, and I believe it was posted by the mysql developers themselves. I hope they add it to the mysql connector package some day.
I tested this and it does work.
UPDATE: As mentioned below by Karl M.W... this subclass is no longer needed in v2 of the mysql.connector. The mysql.connector has been updated and now you can use the following option to enable a dictionary cursor.
cursor = db.cursor(dictionary=True)
This example works:
cnx = mysql.connector.connect(database='world')
cursor = cnx.cursor(dictionary=True)
cursor.execute("SELECT * FROM country WHERE Continent = 'Europe'")
print("Countries in Europe:")
for row in cursor:
print("* {Name}".format(Name=row['Name']
Keep in mind that in this example, 'Name' is specific to the column name of the database being referenced.
Also, if you want to use stored procedures, do this instead:
cursor.callproc(stored_procedure_name, args)
result = []
for recordset in cursor.stored_results():
for row in recordset:
result.append(dict(zip(recordset.column_names,row)))
where stored_procedure_name is the name of the stored procedure to use and args is the list of arguments for that stored procedure (leave this field empty like [] if no arguments to pass in).
This is an example from the MySQL documentation found here: http://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursordict.html
Using Python 3.6.2 and MySQLdb version 1.3.10, I got this to work with:
import MySQLdb
import MySQLdb.cursors
...
conn = MySQLdb.connect(host='...',
<connection info>,
cursorclass=MySQLdb.cursors.DictCursor)
try:
with conn.cursor() as cursor:
query = '<SQL>'
data = cursor.fetchall()
for record in data:
... record['<field name>'] ...
finally:
conn.close()
I'm using PyCharm, and simply dug into the MySQLdb modules connections.py and cursors.py.
I had the same problem with the default cursor returning tuples with no column names.
The answer is here:
Getting error while using MySQLdb.cursors.DictCursor in MYSQL_CURSORCLASS
app.config["MYSQL_CURSORCLASS"] = "DictCursor"
I am currently connecting to a Sybase 15.7 server using sybpydb. It seems to connect fine:
import sys
sys.path.append('/dba/sybase/ase/15.7/OCS-15_0/python/python26_64r/lib')
sys.path.append('/dba/sybase/ase/15.7/OCS-15_0/lib')
import sybpydb
conn = sybpydb.connect(user='usr', password='pass', servername='serv')
is working fine. Changing any of my connection details results in a connection error.
I then select a database:
curr = conn.cursor()
curr.execute('use db_1')
however, now when I try to run queries, it always returns None
print curr.execute('select * from table_1')
I have tried running the use and select queries in the same execute, I have tried including go commands after each, I have tried using curr.connection.commit() after each, all with no success. I have confirmed, using dbartisan and isql, that the same queries I am using return entries.
Why am I not getting results from my queries in python?
EDIT:
Just some additional info. In order to get the sybpydb import to work, I had to change two environment variables. I added the lib paths (the same ones that I added to sys.path) to $LD_LIBRARY_PATH, i.e.:
setenv LD_LIBRARY_PATH "$LD_LIBRARY_PATH":dba/sybase/ase/15.7/OCS-15_0/python/python26_64r/lib:/dba/sybase/ase/15.7/OCS-15_0/lib
and I had to change the SYBASE path from 12.5 to 15.7. All this was done in csh.
If I print conn.error(), after every curr.execute(), I get:
("Server message: number(5701) severity(10) state(2) line(0)\n\tChanged database context to 'master'.\n\n", 5701)
I completely understand where you might be confused by the documentation. Its doesn't seem to be on par with other db extensions (e.g. psycopg2).
When connecting with most standard db extensions you can specify a database. Then, when you want to get the data back from a SELECT query, you either use fetch (an ok way to do it) or the iterator (the more pythonic way to do it).
import sybpydb as sybase
conn = sybase.connect(user='usr', password='pass', servername='serv')
cur = conn.cursor()
cur.execute("use db_1")
cur.execute("SELECT * FROM table_1")
print "Query Returned %d row(s)" % cur.rowcount
for row in cur:
print row
# Alternate less-pythonic way to read query results
# for row in cur.fetchall():
# print row
Give that a try and let us know if it works.
Python 3.x working solution:
import sybpydb
try:
conn = sybpydb.connect(dsn="Servername=serv;Username=usr;Password=pass")
cur = conn.cursor()
cur.execute('select * from db_1..table_1')
# table header
header = tuple(col[0] for col in cur.description)
print('\t'.join(header))
print('-' * 60)
res = cur.fetchall()
for row in res:
line = '\t'.join(str(col) for col in row)
print(line)
cur.close()
conn.close()
except sybpydb.Error:
for err in cur.connection.messages:
print(f'Error {err[0]}, Value {err[1]}')