Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial Pass Informix DBHelper #25

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

feenster
Copy link

@feenster feenster commented Feb 5, 2020

first pass informix DbHelper

first pass informix DbHelper
@@ -0,0 +1,79 @@
"""
Database helper for Postgres
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Informix


class InformixDbHelper(DbHelper):
"""
Postgres db helper class
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Informix

"""
Returns connection string for sql alchemy
"""
password = self.get_password(password_variable)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactor for Informix connection string. This is prime TDD territory once you have manually figured out what the SQLAlchemy string is supposed to look like.

return (f'postgresql://{db_params.user}:{password}@'
f'{db_params.host}:{db_params.port}/{db_params.dbname}')

@staticmethod
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this - it's only required for PostgreSQL

def cursor(conn):
"""
Return a cursor on current connection. This implementation allows
SQLite cursor to be used as context manager as with other db types.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Informix

pyodbc
psycopg2-binary
twine
alabaster==0.7.12
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strip version numbers as we want to be as flexible as possible. It is probably easier just to add ibm-db and pytest-sugar to the existing list.

@@ -1,11 +1,12 @@
"""Unit tests for db_helpers module."""
from unittest.mock import Mock
import pytest
import pyodbc
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure why pyodbc moved places here, but it should be in the group with the third-party imports, rather than the standard library ones.

@@ -26,6 +27,8 @@

SQLITEDB = DbParams(dbtype='SQLITE', filename='/myfile.db')

INFORMIXDB = DbParams(dbtype='INFORMIX', database='testDb', hostname='localhost', port='1111', protocol='tcpip',uid='user' )
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line length. Flake8 is set to 120, but less is better.

@@ -43,7 +46,8 @@ def test_oracle_connect_exceptions():
'DRIVER=test driver;SERVER=tcp:server;PORT=1521;DATABASE=testdb;UID=testuser;PWD=mypassword'), # NOQA
(POSTGRESDB, psycopg2,
'host=server port=1521 dbname=testdb user=testuser password=mypassword'),
(SQLITEDB, sqlite3, '/myfile.db')
(SQLITEDB, sqlite3, '/myfile.db'),
(INFORMIXDB, ibm_db_dbi, 'database=testDb;hostname=localhost;port=1111;protocol=tcpip;uid=user;pwd=mypassword')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line length. See MSSQLDB example above for line splitting and turning off Flake8 check for line.

@volcan01010
Copy link
Collaborator

Thanks @feenster,

There are a few tweaks to make before this is ready to merge:

Flake8 failure in CI pipeline

The CI pipeline runs flake8 against the etlhelper and test directories. It found the following:

$ flake8 etlhelper test
etlhelper/db_helpers/informix.py:68:5: E303 too many blank lines (2)
test/unit/test_db_helpers.py:30:112: E231 missing whitespace after ','
test/unit/test_db_helpers.py:30:121: E501 line too long (124 > 120 characters)
test/unit/test_db_helpers.py:30:123: E202 whitespace before ')'

SQLAlchemy conn_string test and function

DbHelpers have a method to create a SQLAlchemy connection string, but we haven't implemented that yet for InformixDbHelper. Please add another parameterized test and make it pass.

Setup.py

setup.py defines extras_require options for each database type. Please add an entry for Informix. This will allow users to install Informix driver automatically with pip install etlhelper[informix].

README

Please add a line in the database drivers instructions for [informix]. Please also add a section for "IBM Informix" underneath the "pyodbc" section that explains that the driver is hard-coded to used protocol=tcpip and that this may need to be configured on the server.

See also the review comments on the changes to the files.

It was fun hacking on this yesterday.

@volcan01010
Copy link
Collaborator

If you were super keen, you could add integration tests against a Dockerised instance. See CONTRIBUTING.md for details and test/integration/test_db/test_sqlite.py for a template. It's quite a bit more work, though and probably constitutes a separate ticket.

@volcan01010
Copy link
Collaborator

volcan01010 commented May 25, 2020

Informix database notes.

Docker info: https://github.com/informix/informix-dockerhub-readme/blob/master/14.10.FC1/informix-developer-database.md

Docker run command:

docker run -it --name ifx -h ifx -p 9088:9088 -e LICENSE=accept ibmcom/informix-developer-database:latest
from etlhelper import connect, DbParams, execute, get_rows
import os

os.environ['IFX_PASSWORD'] = 'in4mix'
ifxdb = DbParams(dbtype="INFORMIX",
          hostname='localhost', port=9088,
          uid='informix', database='informix')

conn = connect(ifxdb, 'IFX_PASSWORD')

Gets this error:

ETLHelperConnectionError: Error connecting to database=informix;hostname=localhost;port=9088;protocol=tcpip;uid=informix;pwd=in4mix via dbapi: ibm_db_dbi::OperationalError: Exception('[IBM][CLI Driver] SQL30081N  A communication error has been detected. Communication protocol being used: "TCP/IP".  Communication API being used: "SOCKETS".  Location where the error was detected: "127.0.0.1".  Communication function detecting the error: "recv".  Protocol specific error code(s): "*", "*", "0".  SQLSTATE=08001 SQLCODE=-30081')

Why can't I connect on TCP/IP? The port is correct. And what should the database value be?

@dvalters dvalters changed the base branch from master to main August 20, 2020 11:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants