I am trying to create tables in a MS Access DB with python using pyodbc but when I run my script no tables are created and no errors are given. My code:
#!/usr/bin/env python
import pyodbc
con = pyodbc.connect(r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=Z:\Data\Instruments\testDB.accdb; Provider=MSDASQL;')
cur = con.cursor()
string = "CREATE TABLE TestTable(symbol varchar(15), leverage double, shares integer, price double)"
cur.execute(string)
What could be wrong?
You need to commit the transaction:
import pyodbc
con = pyodbc.connect(r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=Z:\Data\Instruments\testDB.accdb; Provider=MSDASQL;')
cur = con.cursor()
string = "CREATE TABLE TestTable(symbol varchar(15), leverage double, shares integer, price double)"
cur.execute(string)
con.commit()
Additional solutions that do not require a manual commit are:
Set autocommit = True when the connection instance is created.
Eg:
con = pyodbc.connect(your_connection_string, autocommit = True)
OR
Use a with statement that, according to Python Database connection Close, will commit anything before the connection is deleted at the end of the with block.
Eg:
with pyodbc.connect(your_connection_string) as con:
CREATE_TABLE_CODE_WITHOUT_COMMIT
UNRELATED_CODE
Related
I'm trying to add a column to an MS Access database table using pyodbc and Python 3.5.
Using the expression
self.cursor.execute("ALTER TABLE data ADD COLUMN testColumn TEXT(10)")
works fine, but when I try to add a default value (DEFAULT "no"), it throws a Syntax error. I've tried multiple combinations, but no luck.
Any help is much appreciated!
Cheers
Sadly, the Access ODBC driver simply does not support the DEFAULT clause for a column in CREATE/ALTER TABLE statements. The ODBC driver and OLEDB provider for Access have diverged somewhat in their DDL support, so unfortunately we can get inconsistent results for the same DDL statement as illustrated by the following VBScript code using ADO:
OLEDB works fine ...
Option Explicit
Dim conn
Set conn = CreateObject("ADODB.Connection")
Dim connStr
connStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Public\mdbTest.mdb"
conn.Open connStr
On Error Resume Next
conn.Execute "DROP TABLE Cheeses"
On Error GoTo 0
conn.Execute "CREATE TABLE Cheeses (Id LONG PRIMARY KEY, CheeseName TEXT(50) DEFAULT 'Cheddar')"
conn.Execute "INSERT INTO Cheeses (Id) VALUES (1)"
Dim rst
Set rst = CreateObject("ADODB.Recordset")
rst.Open "SELECT CheeseName FROM Cheeses WHERE Id = 1", conn
If rst("CheeseName").Value = "Cheddar" Then
WScript.Echo "Success"
End If
conn.Close
... but if we change the connection string to use ODBC ...
connStr = "Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=C:\Users\Public\mdbTest.mdb"
... then our attempt to execute the CREATE TABLE statement fails with
Microsoft OLE DB Provider for ODBC Drivers: [Microsoft][ODBC Microsoft Access Driver] Syntax error in CREATE TABLE statement.
TL;DR - You can't use the DEFAULT clause in a CREATE/ALTER TABLE statement under pyodbc.
I am accessing a MS Access Database in Python 3.6 using pyodbc library. I can read a table, no problems. The I created a simple table (Employee). I inserted records. I was able to fetch the records too by reading the table, no problems.
I also listed the tables in the MS Access DB. Employee table shows in the list.
But when I open up the MS Access Database, I do not find the table. I changed MS Access DB to show hidden and system objects. Employee table doesn't show up.
What am I doing wrong?
Thanks
Here is the code:
import pyodbc
db_file = r'''C:\TickData2018\StooqDataAnalysis.accdb'''
user = 'admin'
password = ''
odbc_conn_str = 'DRIVER={Microsoft Access Driver (*.accdb)};DBQ=%s;UID=%s;PWD=%s' %\
(db_file, user, password)
# Or, for newer versions of the Access drivers:
odbc_conn_str = 'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=%s;UID=%s;PWD=%s' %\
(db_file, user, password)
conn = pyodbc.connect(odbc_conn_str)
print("connection made")
c = conn.cursor()
c.execute("SELECT * FROM 5MtsBaseForAnalysisSorted")
list1 = c.fetchmany(2)
print(list1[0][0])
print(list1[0][1])
print(list1[0][2])
try:
c.execute("""CREATE TABLE employee(
first text,
last text,
pay integer
);""")
except Exception as e:
print(e)
conn.commit
c.execute("INSERT INTO employee VALUES ('Krishna', 'Sundar', 50000)")
c.execute("INSERT INTO employee VALUES ('Divya', 'Sundar', 70000)")
c.execute("INSERT INTO employee VALUES ('Panka', 'Sundar', 70000)")
conn.commit
c.execute("SELECT * FROM employee")
print(c.fetchall())
c.tables()
rows = c.fetchall()
for row in rows:
print(row)
c.close()
del c
conn.close()
This is a general Python object model where you need to call the actual function and not its bounded name. Specifically, your commit lines are not correct where
conn.commit
Should be with open/close parentheses:
conn.commit()
Another way to see the difference is by reviewing the object's type:
type(conn.commit)
# <built-in method commit of pyodbc.Connection object at 0x000000000B772E40>
type(conn.commit())
# NoneType
I did reproduce your issue with exact code and adding parentheses resolved the issue.
An additional solution to manually committing is to set autocommit = True when the connection instance is created.
Eg:
conn = pyodbc.connect(odbc_conn_str, autocommit = True)
There are a lot of tips online on how to use pyodbc to run a query in MS Access 2007, but all those queries are coded in the Python script itself. I would like to use pyodbc to call the queries already saved in MS Access. How can I do that?
If the saved query in Access is a simple SELECT query with no parameters then the Access ODBC driver exposes it as a View so all you need to do is use the query name just like it was a table:
import pyodbc
connStr = (
r"Driver={Microsoft Access Driver (*.mdb, *.accdb)};"
r"DBQ=C:\Users\Public\Database1.accdb;"
)
cnxn = pyodbc.connect(connStr)
sql = """\
SELECT * FROM mySavedSelectQueryInAccess
"""
crsr = cnxn.execute(sql)
for row in crsr:
print(row)
crsr.close()
cnxn.close()
If the query is some other type of query (e.g., SELECT with parameters, INSERT, UPDATE, ...) then the Access ODBC driver exposes them as Stored Procedures so you need to use the ODBC {CALL ...} syntax, as in
import pyodbc
connStr = (
r"Driver={Microsoft Access Driver (*.mdb, *.accdb)};"
r"DBQ=C:\Users\Public\Database1.accdb;"
)
cnxn = pyodbc.connect(connStr)
sql = """\
{CALL mySavedUpdateQueryInAccess}
"""
crsr = cnxn.execute(sql)
cnxn.commit()
crsr.close()
cnxn.close()
Basically I'm trying to update Column1_mbgl field data in Table1, all based in MS Access database. The script gets executed without any errors, but when the table is checked no update occurred. I have tried two options as shown in the code without any success. The second option is the SQL code generated directly from MS Access query. Can anybody suggest what I'm missing in the code?
#import pypyodbc
import pyodbc
# MS ACCESS DB CONNECTION
pyodbc.lowercase = False
conn = pyodbc.connect(
r"Driver={Microsoft Access Driver (*.mdb, *.accdb)};" +
r"Dbq=C:\temp\DB_access.accdb;")
# OPEN CURSOR AND EXECUTE SQL
cur = conn.cursor()
# Option 1 - no error and no update
cur.execute("UPDATE Table1 SET Column1_mbGL = Column2_mbGL-0.3 WHERE ((Column3_name='PZ01') AND (DateTime Between #6/14/2016 14:0:0# AND #6/16/2016 12:0:0#) AND (TYPE='LOG'))");
# Option 2 - no error and no update
#cur.execute("UPDATE Table1 SET Table1.Column1_mbGL = [Table1]![Column2_mbGL]-0.3 WHERE (((Table1.Column3_name)='PZ01') AND ((Table1.DateTime) Between #6/14/2016 14:0:0# And #6/16/2016 12:0:0#) AND ((Table1.TYPE)='LOG'))");
cur.close()
conn.close()
You forgot to conn.commit() after executing your UPDATE query. The Python database API specifies that connections open with "autocommit" off by default, so an explicit commit is needed.
I am able to connect Python 3.4 and Postgres but I am the query is not successfully getting executed. For e.g, the table below is not getting created
import psycopg2
from psycopg2 import connect
try:
conn = psycopg2.connect("dbname='postgres' user='postgres' host='localhost' password='postgres'")
print("Database connected!")
cur = conn.cursor()
cur.execute("""CREATE TABLE DEPARTMENT(
ID INT PRIMARY KEY NOT NULL,
DEPT CHAR(50) NOT NULL,
EMP_ID INT NOT NULL
)""")
except:
print("I am unable to connect to the database")
Just add
conn.commit()
after you've run the execute.
Relational databases have the concept of transaction, which happen (if at all) "atomically" (all-or-none). You need to commit a transaction to actually make it take place; until you've done that, you keep the option to rollback it instead, to have no changes made to the DB if you've found something iffy on the way.