Unable to connect to SQL Server via pymssql - python

I am attempting to connect to SQL Server running on Windows XP system from a *nix system on a local server via pymssql. However, the connection fails as shown below
db = pymssql.connect(host='192.168.1.102',user='www',password='test',database='TestDB')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "pymssql.pyx", line 457, in pymssql.connect (pymssql.c:6041)
raise InterfaceError(e[0])
pymssql.InterfaceError: Connection to the database failed for an unknown reason.
Things I've tried:
Set SQL Server and browser to run as a network server.
Setup a user 'www'. I also tested this user locally in SQL Studio.
Turned off Windows firewall (temporarily of course).
I am missing SOMETHING - I just don't know what it is. I tried all of the infinite menu options on Windows to no avail. One thing I noticed is that if the Windows Firewall is on (I setup an exception for SQL Server) python pauses a long time and then gives the error. If the firewall is off the error is instant.
Are there any logs I can look at in SQL Server?

Got it! I think the source of the problem was not giving Free TDS the attention it needs. Free TDS is apparently the driver behind pymssql and provides for connectivity to other databases - SQL Server being one of them.
The freetds.conf file is located in /usr/local/etc on my system (Mac Book Pro).
This file contains the defaults from the install. However, I had previously added a definition so that I could connect but forgot about it and unfortunately did not take notes on it.
Anyway, here is an example of what I appended to freetds.conf:
[SomeDB]
host = 192.168.1.102
port = 1219
tds version = 7.0
However, what is puzzling is that I set the port to 1219. I had it set manually to 1433 in SQL Studio. Also, I am using TDS version 0.82 so I don't know how 7.0 fits in.
Next, I tested connectivity using 'tsql' as follows:
tsql -S SomeDB -U www
I enter the password and get a command-line which allows for SQL queries.
Next, I tested connecting using pymssql as follows:
db = pymssql.connect(host='SomeDB',user='www',password='cylon',database='TestDB')
As you can see, I needed to use the host name from the freetds.conf file and NOT the IP directly. I then tested a simple query with additional python code to insure I could read from the database.
I hope this helps someone else in the future.

It looks like you've got this solved, but for anybody else from google that lands here: check to make sure mixed-mode authorization is turned on on your MS SQL Server. It defaults to only allowing Windows authorization, and that will cause this error in pymssql.

is it a windows machine u working on? specify the port 1433.
it seems to be a bug in the mssql client api, which tries to use Namedpipes instead of TCP/IP.

Related

SSL connection to MySQL dB failed

I have a python script running on an Amazon EC2 instance (linux) that scrapes the data from a source and outputs a pandas dataframe to me. I want to send this dataframe to MySQL on Amazon RDS. But when I run the script, it throws me the following error:
sqlalchemy.exc.InterfaceError: (mysql.connector.errors.InterfaceError) 2026 (HY000): SSL connection error: SSL_CTX_set_tmp_dh failed
Before executing the script on an ec2 instance, I was running it on my local machine and it was working fine. Meaning, I was able to send the data to the RDS scraped by my scraper. But now that I am running the script on EC2, it is showing me SSL connection errors.
I might not have configured the EC2 instance correctly or might have forgotten to install something. I don't work with SSL much, so I'm finding it difficult figuring out how this is supposed to be set up. Any pointers, even obvious ones, will likely help at this stage.
I have tried some of the solutions that i found on stack but none of them worked. This is my code to connect to the database:
def dbConnect():
end_point = xxx
username = xxx
password = xxx
port=3306
global dbname
dbname=xxx
conn = pymysql.connect(end_point, user=username,port=port,passwd=password, db=dbname)
global eng
eng=create_engine('mysql+mysqlconnector://xxx:xxx#xxx:3306')
return dbname,eng
The solution is to downgrade openssl.
conda install openssl=1.0.2p
See this thread for more information:
https://github.com/ContinuumIO/anaconda-issues/issues/10646
Also this other question.
I have something very similar, although I use PuTTy for the SSH to create a port forwared tunnel.
Make sure you have the security groups set up correctly between your EC2 instance and RDS too.

'ORA-21561: OID generation failed for remote Oracle 12c XE Instance - Oracle on Windows 10 client (cx_Oracle using python) on Mac

I am trying to connect to the Oracle instance which is running on Windows 10 through python using cx_Oracle package from a mac machine.
Now while connecting it throw below error.
'ORA-21561: OID generation failed\n'
My Sample code:
import cx_Oracle
DSN = cx_Oracle.makedsn(host=server, port=port, service_name=database)
# Below is the DNS
# (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.1.9)(PORT=50244))(CONNECT_DATA=(SERVICE_NAME=devXDB)))
con = cx_Oracle.Connection(user, password, DSN)
However I am able to connect from same machine (mac) using SQL developer and PyCharm's database browser. I searched across and did not find any solution related to remote instance. The solutions suggested for seems to be working only for the local instances in which one has to edit/update etc/hosts or related file on windows 10.
Thanks in advance.
This was indeed the problem of /etc/hosts file issue.
One thing to note here even if the oracle instance is running on a remote machine you client machine's (from where you are connecting to the oracle instance) /etc/hosts file should have the entry like this.
##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting. Do not change this entry.
##
127.0.0.1 localhost localhost.localdomain Amits-iMac.local
Replace 'Amits-iMac.local' to your client's hostname.

Python mysql.connector connection DatabaseError - host is blocked occurring when running from remote vm

I am attempting to connect to a remote MySQL DB from a virtual machine (Ubuntu, running on Azure).
When I access the DB from my computer via the command line, I enter:
mysql -u username -h www.foobar.nyc -p
Which prompts me for the password. When I enter the password, it successfully logs me in to the remote db.
Now when I perform the same actions as above, but instead from a remote vm that I have ssh into, I get the following error returned after entering my pw.
ERROR 1129 (HY000): Host 'xxx.xx.xxx.xxx' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'
Googling this error brings me to: http://dev.mysql.com/doc/refman/5.7/en/blocked-host.html
I'd like to understand why I am getting so many connection errors - is that normal? Is there a setting perhaps with Azure that I need to look into? I know Azure has the endpoints manager. When using the Python mysql library, it reads that errors occurring File "/site-packages/mysql/connector/connection.py", line 418, in _open_connection on self._do_handshake()
What I hope to gain from this question:
Understand why "many" errors are occurring - what is causing this and is receiving such high numbers of errors normal (as some comments in the MySQL documentation I linked to appear to suggest).
Understand the differences that enable the same actions to work from local in command line but not from command line when ssh into remote Azure based vm.
Thanks.
1.Understand why "many" errors are occurring - what is causing this and is receiving such high numbers of errors normal (as some comments in the MySQL documentation I linked to appear to suggest).
Per my experience, you can check the mysql error logs, details on enabling error logs are # How to see log files in MySQL?.
2.Understand the differences that enable the same actions to work from local in command line but not from command line when ssh into remote Azure based vm.
Based on the latest comment you provided, the new created VM was not experiencing the same issue, it may not be an azure platform specific related issue.

sqlalchemy connection identical credentials refused when run on different machines

I have a problem which seems impossible to me, meaning I am fundamentally misunderstanding something. I've written a simple API using flask (a python library). This api, among other things, connects to a mysql server running on a remote web server. I am using the sqlalchemy library to perform this connection.
The connection string is quite simple. It looks like this:
db =create_engine('mysql+mysqlconnector://{user}:{password}#{host}:{port}/{database}'.format(user=Constants.Sql.USER, password=Constants.Sql.PASS, host=Constants.Sql.HOST, port=Constants.Sql.PORT, database=Constants.Sql.DATABASE))
connection = db.connect()
On my development machine this all works fine. However, when I deploy the api to a different remote machine, it doesn't work. I get the error:
sqlalchemy.exc.ProgrammingError: (ProgrammingError) 1045 (28000): Access denied for user 'user'#'domain' (using password: YES) None None
This doesn't make any sense to me because it is using exactly the same credentials (they are hard coded).
The working environment is a windows machine, the environment throwing the error is ubuntu 14.04. Both the windows and ubuntu machines are remote to the web server on which the database is running, so it can't be some weird localhost thing.
I am totally stumped with this. If anyone could give me some advice I'd really appreciate it!
Maybe the database only accepts connections from a particular IP address. That would explain why same username and password would succeed on one and fail on the other.
GRANT includes IP address information. Look at the MySQL documentation. Or this tutorial:
https://alvinalexander.com/blog/post/mysql/add-user-mysql/

Connecting to MS SQL Server using python on linux with 'Windows Credentials'

Is there any way to connect to an MS SQL Server database with python on linux using Windows Domain Credentials?
I can connect perfectly fine from my windows machine using Windows Credentials, but attempting to do the same from a linux python with pyodbs + freetds + unixodbc
>>import pyodbc
>>conn = pyodbc.connect("DRIVER={FreeTDS};SERVER=servername;UID=username;PWD=password;DATABASE=dbname")
results in this error:
class 'pyodbc.Error'>: ('28000', '[28000] [unixODBC][FreeTDS][SQL Server]Login incorrect. (20014) (SQLDriverConnectW)')
I'm sure the password is written correctly, but I've tried many different combinations of username:
DOMAIN\username
DOMAIN\\username
or even
UID=username;DOMAIN=domain
to no avail. Any ideas?
As of at least March 2013, this seems to work out of the box with FreeTDS. I specified the TDS protocol version for good measure--not sure if that makes the difference:
connStr = "DRIVER={{FreeTDS}};SERVER={0};PORT=1433;TDS_Version=7.2;UID={1}\\{2};PWD={3}".format(hostname, active_directory_domain, username, password)
Integrated authentication also appears to be supported in Microsoft's official driver for linux: http://msdn.microsoft.com/en-us/library/hh568450.aspx . I'm not sure how many Linux distributions it actually works on or how much of the source is available. They explicitly mention RHEL 5 and 6 and some dependencies on the download page.
As pointed out in one of the comments, this answer is quite stale by now. I regularly and routinely use GSSAPI to authenticate from Linux to SQL Server 2008 R2 but mostly with the EasySoft ODBC manager and the (commercial) EasySoft ODBC SQL Server driver.
In early 2009, a colleague and I managed to connect to a SQL Server 2005 instance from Solaris 10 using GSSAPI (Kerberos credentials) using DBB::Perl over a FreeTDS build linked against a particular version of the MIT kerberos libraries. The trick was -- and this is a little bit difficult to believe but I have verified it by looking through the FreeTDS source code -- to specify a zero-length user_name. If the length of the user_name string is 0 then the FreeTDS code will attempt to use GSSAPI (if that support has been compiled in). I have not been able to do this via Python and pyodbc as I could not figure out a way of getting ODBC to pass down a zero-length user_name.
Here in the perl code .. there are multiple opportunities for breakage wrt configuration files such as .freetds.conf etc. I seem to recall that the principal had to be in uppercase but my notes seem to be in disagreement with that.
$serverprincipal = 'MSSQLSvc/foo.bar.yourdomain.com:1433#YOURDOMAIN.COM';
$dbh = DBI->connect("dbi:Sybase:server=THESERVERNAME;kerberos=$serverprincipal", '', '');
You will have to know how to use the setspn utility in order to get the SQL Server server to use the appropriate security principal name.
I do not have any knowledge of the kerberos side of things because our environment was set up by an out and out Kerberos guru and has fancy stuff like mutual trust set up between the AD domain that the SQL Server is running in and the Kerberos domain that my client was running in.
There is some code http://code.google.com/p/libsqljdbc-auth/ which does GSSAPI authentication from Linux to SQL Server but it is Java only. The author (who seems to know his stuff) also has contributed a similar patch to the jTDS project which works with more recent versions of Java that have GSSAPI built in.
So the pieces are all there, it is just a big tangled mess trying to get them all to work together. I found the pyodbc to unixODBC to FreeTDS odbc to TDS integration pretty hard to trace/debug. The perl stuff because it was a pretty thin wrapper on top to CT-Lib was much easier to get going.
Probably a bit too late to help you out - but I encountered the same issue. At the time of writing, the latest version of pyodbc allows me to login with windows credentials. Just leave the UID field blank in your connection string like so:
cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=myserverinstance;DATABASE=mydatabase;UID=;PWD=mypassword')
Now this is using your existing windows credentials when you're logged on... not sure how to specify any arb windows domain credentials...
I haven't done it in a while, but I remember the whole unixodbc + FreeTDS + pyodbc thing being a little tricky. However, it can be done, and once setup it's not that hard.
This website provides very good instructions:
http://www.pauldeden.com/2008/12/how-to-setup-pyodbc-to-connect-to-mssql.html (archived copy on Web Archive)
Also, in my experience pyodbc had issues compiling/running on 64 bit Linux machines. Because of that we eventually used ceODBC. ceODBC isn't quite as stable as pyodbc (encountered more unexpected bugs than in pyodbc when running in python prorgram), but it is very easy to get up and running on Linux 64 bit.
I don't believe you'll be able to log in to a windows domain account in this way. You need to set up a user in sql directly for this manner of passing credentials.

Categories