"transaction interface" error when updating table on linked server - python

I'm getting this error when trying to update a db2 database that is a linked server on our SQL Server db.
ERROR:root:('42000', '[42000] [Microsoft][ODBC SQL Server Driver][SQL Server]The requested operation could not be performed because OLE DB provider "IBMDA400" for linked server "iSeries" does not support the required transaction interface. (7390) (SQLExecDirectW)')
I am connecting to sql server via pyodbc and can run sql scripts with no issues. Here is the sql I get the error with
sql3 = " exec ('UPDATE SVCEN2DEV.SRVMAST SET SVRMVD = ? WHERE svtype != ''*DCS-'' AND svcid = ? and svacct = ? ') AT [iSeries]"
db.execute(sql3, (row[2],srvid,row[0]))
db.commit()
And just in case here is my connection string using pyodbc:
conn = pyodbc.connect("DRIVER={SQL Server};SERVER="+ Config_Main.dbServer +";DATABASE="+ Config_Main.encludeName +";UID="+ Config_Main.encludeUser +";PWD=" + Config_Main.encludePass)
db = conn.cursor()
Also note that this query runs just fine in SSMS. I have also tried the openquery method but had no luck. Any ideas?

Python's DB API 2.0 specifies that, by default, connections should open with autocommit "off". This results in all database operations being performed in a transaction that must be explicitly committed (or rolled back) in the Python code.
When a pyodbc connection with autocommit = False (the default) sends an UPDATE to the SQL Server, that UPDATE is enclosed in a Local Transaction managed by SQL Server. When the SQL Server determines that the target table is on a Linked Server it tries to promote the transaction to a Distributed Transaction managed by MSDTC. If the connection technology used to manage the Linked Server does not support Distributed Transactions then the operation will fail.
This issue can often be avoided by ensuring that the pyodbc connection has autocommit enabled, either by
cnxn = pyodbc.connect(conn_str, autocommit=True)
or
cnxn = pyodbc.connect(conn_str)
cnxn.autocommit = True
That will send each SQL statement individually, without being wrapped in an implicit transaction.

Related

How do I edit Azure SQL Database using pyodbc/odbc?

I wrote a Python program that web scraped a website and added the results to a Microsoft Access database. I now want to run the script again, with it adding the data to an Azure SQL database. I keep getting this error.
A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections.
I have tried t edit the settings of the database to no avail. Could someone tell me what settings to apply to the database? I also tried to see if there was a way to run the Python script inside azure to try to avoid the problem. Is this possible?
cnxn = pyodbc.connect(r'Driver={ODBC Driver 18 for SQL Server};Server=tcp:servername.database.windows.net,1433;Database=sizedb3;Uid={your_user_name};Pwd={your_password_here};Encrypt=yes;TrustServerCertificate=no;Connection Timeout=30;Authentication=ActiveDirectoryPassword')
I tried this driver. I have downloaded the driver from Microsoft's website. This driver is a connection string in the ODBC section of the Azure SQL database in the Azure portal.
I tried running the below python code to connect to Azure SQL DB with Azure AD authentication.
Code:-
import pyodbc
conn = pyodbc.connect('Driver={ODBC Driver 17 for SQL Server};'
'Server=tcp:siliconserver.database.windows.net,1433;'
'Database=silicondb;'
'Uid=xxxser#sid24desaioutlook.onmicrosoft.com;'
'Pwd=xxxxxxxxxx#123;'
'authentication=ActiveDirectoryPassword')
cursor = conn.cursor()
cursor.execute('SELECT * FROM StudentReviews')
for i in cursor:
print(i)
cursor.close()
conn.close()
Output:-
Make sure you have allowed your Client IP in your Azure SQL server Networking tab like below:-
I tried to remove one syntax/spelling from my Azure SQL connection string and got the same error code as yours like below:-
You can validate your connection string server spelling and syntax from your Azure SQL server DB > Connection String > like below:-
Also, Make sure you have added your client IP and allowed it in your Azure SQL Server like below:-

SQL Connect error in Python(Windows): severity 9:\nAdaptive Server connection failed

Not able to connect to Azure DB. I get the following error while connecting via Python.
I'm able to connect to my usual SQL environment
import pandas as pd
import pymssql
connPDW = pymssql.connect(host=r'dwprd01.database.windows.net', user=r'internal\admaaron',password='',database='')
connPDW.autocommit(True)
cursor = connPDW.cursor()
conn.autocommit(True)
cursor = conn.cursor()
sql = """
select Top (10) * from TableName
"""
cursor.execute(sql);
Run without errors.
Just according to your code, there is an obvious issue of connecting Azure SQL Database by pymssql package in Python which use the incorrect user format and lack of the values of password and database parameters.
Please follow the offical document Step 3: Proof of concept connecting to SQL using pymssql carefully to change your code correctly.
If you have an instance of Azure SQL Database with the connection string of ODBC, such as Driver={ODBC Driver 13 for SQL Server};Server=tcp:<your hostname>.database.windows.net,1433;Database=<your database name>;Uid=<username>#<host>;Pwd=<your_password>;Encrypt=yes;TrustServerCertificate=no;Connection Timeout=30; show in the Connection strings tab of your SQL Database on Azure portal.
Then, your code should be like below
hostname = '<your hostname>'
server = f"{hostname}.database.windows.net"
username = '<your username>'
user = f"{username}#{hostname}"
password = '<your password>'
database = '<your database name>'
import pymssql
conn = pymssql.connect(server=server, user=user, password=password, database=database)
Meanwhile, just additional note for the version of Azure SQL Database and MS SQL Server are 2008+ like the latest Azure SQL Database, you should use the ODBC Driver connection string which be started with DRIVER={ODBC Driver 17 for SQL Server};, not 13 show in the connection string of Azure portal if using ODBC driver for Python with pyodbc, please refer to the offical document Step 3: Proof of concept connecting to SQL using pyodbc.

Use Turbodbc to connect to SQL Server, simple select

I cannot get Python Turbodbc to connect to a Sql Server table, simple as that seems, to read or write user tables. However I have established ODBC connection, and can print a list of objects from it.
1 List objects from server to test connection. Seems to work:
from turbodbc import connect, make_options
options = make_options(prefer_unicode=True)
connection = connect(dsn='FPA', turbodbc_options=options)
cursor = connection.cursor()
cursor.execute('''SELECT * FROM sys.objects WHERE schema_id = SCHEMA_ID('dbo');''')
2 Simple Select: Does not work
cursor.execute('''SELECT * from [dbo].[Kits_Rec];''')
From #1 I get
From # 2 message: [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Invalid object name 'dbo.Kits_Rec'.
enter image description here
A SQL Server contains multiple databases, your dsn "FPA" probably doesn't specify the database name, so you are connecting to the master database instead of the database containing your Kits_Rec table.
Fix that dsn entry to specify the correct database, or use this syntax instead :
connection = connect(driver="MSSQL Driver",
server="hostname",
port="1433",
database="myDataBase",
uid="myUsername",
pwd="myPassword")

Connect to Database on local host with sqlite3 in python

I have a database that I am running on my local machine which I can access through Microsoft SQL Server Manager Studio. I connect to this server "JIMS-LAPTOP\SQLEXPRESS" and then I can run queries through the manager. However I need to be able to connect to this database and work with it through python.
When I try to connect using sqlite3 like
conn = sqlite3.connect("JIMS-LAPTOP\SQLEXPRESS")
I get an unable to open database file error
I tried accessing the temporary file directly like this
conn = sqlite3.connect("C:\Users\Jim Notaro\AppData\Local\Temp\~vs13A7.sql")
c = conn.cursor()
c.execute("SELECT name FROM sqlite_master WHERE type = \"table\"")
print c.fetchall()
Which allows me to access a database but it is completely empty (No tables are displayed)
I also tried connecting like this
conn = sqlite3.connect("SQL SERVER (SQLEXPRESS)")
Which is what the name is in the sql server configuration manager but that also returns a blank database.
I'm not sure how I am suppose to be connecting to the database using python
You can't use sqlite3 to connect to SQL server, only to Sqlite databases.
You need to use a driver that can talk to MS SQL, like pyodbc.

Cannot perform a backup or restore operation within a transaction

I am using PyODBC to back up my database, using following code:
SQL_command = """
BACKUP DATABASE [MyDatabase]
TO DISK = N'D:\MSSQL\BACKUP\MyDatabase_20141212.bak' WITH
NOFORMAT
, NOINIT
, NAME = N'MyDatabase_20141212'
, SKIP
, REWIND
, NOUNLOAD
, STATS = 10
"""
conn.cursor.execute(SQL_command)
conn.cursor.commit()
The above code give me an error message:
pyodbc.ProgrammingError:
('42000', '[42000] [Microsoft][ODBC SQL
Server Driver][SQL Server]Cannot perform a backup or restore operation
within a transaction. (3021) (SQLExecDirectW);
[42000] [Microsoft][ODBC SQL Server Driver][SQL Server]BACKUP DATABASE is
terminating abnormally. (3013)')
I tried to run the SQL code in SQL Server, and it works fine.
May I know what is wrong with my code?
Many thanks.
Your error says
Cannot perform a backup or restore operation within a transaction.
Transactions are started by default in pyodbc, so how do you execute a query without creating a transaction? Simply turn on autocommit:
conn.autocommit = true
// do stuff
conn.autocommit = false
The pyodbc FAQ has an entry about this.
By default all pyodbc connections start with a transaction.
You need to turn autocommit on - using the autocommit keyword to the connect function:
conn.autocommit = true
The other answers are correct. You do need to set autocommit. However, the transaction will complete but the backup won't actually be taken because of a quirk in SQL Server and the way it returns status messages for backup and restore operations.
To work around this you need to loop through these return messages until none remain:
SQL_command = """
BACKUP DATABASE [MyDatabase]
TO DISK = N'D:\MSSQL\BACKUP\MyDatabase_20141212.bak' WITH
NOFORMAT
, NOINIT
, NAME = N'MyDatabase_20141212'
, SKIP
, REWIND
, NOUNLOAD
, STATS = 10
"""
conn.cursor.execute(SQL_command)
while conn.cursor.nextset():
pass
conn.cursor.close()

Categories