You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by GitBox <gi...@apache.org> on 2020/03/04 09:54:01 UTC

[GitHub] [airflow] inytar opened a new pull request #7621: [AIRFLOW-6982] add native python exasol support

inytar opened a new pull request #7621: [AIRFLOW-6982] add native python exasol support
URL: https://github.com/apache/airflow/pull/7621
 
 
   This adds exasol DB support, including a hook, connection type &
   operator. The [pyexasol](https://github.com/badoo/pyexasol) library is
   used to interact with the database.
   
   ---
   Issue link: WILL BE INSERTED BY [boring-cyborg](https://github.com/kaxil/boring-cyborg)
   
   Make sure to mark the boxes below before creating PR: [x]
   
   - [x] Description above provides context of the change
   - [x] Commit message/PR title starts with `[AIRFLOW-NNNN]`. AIRFLOW-NNNN = JIRA ID<sup>*</sup>
   - [x] Unit tests coverage for changes (not needed for documentation changes)
   - [x] Commits follow "[How to write a good git commit message](http://chris.beams.io/posts/git-commit/)"
   - [x] Relevant documentation is updated including usage instructions.
   - [x] I will engage committers as explained in [Contribution Workflow Example](https://github.com/apache/airflow/blob/master/CONTRIBUTING.rst#contribution-workflow-example).
   
   <sup>*</sup> For document-only changes commit message can start with `[AIRFLOW-XXXX]`.
   
   ---
   In case of fundamental code change, Airflow Improvement Proposal ([AIP](https://cwiki.apache.org/confluence/display/AIRFLOW/Airflow+Improvements+Proposals)) is needed.
   In case of a new dependency, check compliance with the [ASF 3rd Party License Policy](https://www.apache.org/legal/resolved.html#category-x).
   In case of backwards incompatible changes please leave a note in [UPDATING.md](https://github.com/apache/airflow/blob/master/UPDATING.md).
   Read the [Pull Request Guidelines](https://github.com/apache/airflow/blob/master/CONTRIBUTING.rst#pull-request-guidelines) for more information.
   

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

[GitHub] [airflow] inytar commented on a change in pull request #7621: [AIRFLOW-6982] add native python exasol support

Posted by GitBox <gi...@apache.org>.
inytar commented on a change in pull request #7621: [AIRFLOW-6982] add native python exasol support
URL: https://github.com/apache/airflow/pull/7621#discussion_r388949599
 
 

 ##########
 File path: airflow/providers/exasol/hooks/exasol.py
 ##########
 @@ -0,0 +1,179 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+from contextlib import closing
+
+import pyexasol
+from past.builtins import basestring
+
+from airflow.hooks.dbapi_hook import DbApiHook
+
+
+class ExasolHook(DbApiHook):
+    """
+    Interact with Exasol.
+    You can specify the pyexasol ``compression``, ``encryption``, ``json_lib``
+    and ``client_name``  parameters in the extra field of your connection
+    as ``{"compression": True, "json_lib": "rapidjson", etc}``.
+    See `pyexasol reference
+    <https://github.com/badoo/pyexasol/blob/master/docs/REFERENCE.md#connect>`_
+    for more details.
+    """
+    conn_name_attr = 'exasol_conn_id'
+    default_conn_name = 'exasol_default'
+    supports_autocommit = True
+
+    def __init__(self, *args, **kwargs):
+        super(ExasolHook, self).__init__(*args, **kwargs)
+        self.schema = kwargs.pop("schema", None)
+
+    def get_conn(self):
+        conn_id = getattr(self, self.conn_name_attr)
+        conn = self.get_connection(conn_id)
+        conn_args = dict(
+            dsn='%s:%s' % (conn.host, conn.port),
+            user=conn.login,
+            password=conn.password,
+            schema=self.schema or conn.schema)
+        # check for parameters in conn.extra
+        for arg_name, arg_val in conn.extra_dejson.items():
+            if arg_name in ['compression', 'encryption', 'json_lib', 'client_name']:
+                conn_args[arg_name] = arg_val
+
+        conn = pyexasol.connect(**conn_args)
+        return conn
+
+    def get_pandas_df(self, sql, parameters=None):
+        """
+        Executes the sql and returns a pandas dataframe
+
+        :param sql: the sql statement to be executed (str) or a list of
+            sql statements to execute
+        :type sql: str or list
+        :param parameters: The parameters to render the SQL query with.
+        :type parameters: mapping or iterable
+        """
+        with closing(self.get_conn()) as conn:
+            conn.export_to_pandas(sql, query_params=parameters)
+
+    def get_records(self, sql, parameters=None):
+        """
+        Executes the sql and returns a set of records.
+
+        :param sql: the sql statement to be executed (str) or a list of
+            sql statements to execute
+        :type sql: str or list
+        :param parameters: The parameters to render the SQL query with.
+        :type parameters: mapping or iterable
+        """
+        with closing(self.get_conn()) as conn:
+            with closing(conn.execute(sql, parameters)) as cur:
+                return cur.fetchall()
+
+    def get_first(self, sql, parameters=None):
+        """
+        Executes the sql and returns the first resulting row.
+
+        :param sql: the sql statement to be executed (str) or a list of
+            sql statements to execute
+        :type sql: str or list
+        :param parameters: The parameters to render the SQL query with.
+        :type parameters: mapping or iterable
+        """
+        with closing(self.get_conn()) as conn:
+            with closing(conn.execute(sql, parameters)) as cur:
+                return cur.fetchone()
+
+    def run(self, sql, autocommit=False, parameters=None):
+        """
+        Runs a command or a list of commands. Pass a list of sql
+        statements to the sql parameter to get them to execute
+        sequentially
+
+        :param sql: the sql statement to be executed (str) or a list of
+            sql statements to execute
+        :type sql: str or list
+        :param autocommit: What to set the connection's autocommit setting to
+            before executing the query.
+        :type autocommit: bool
+        :param parameters: The parameters to render the SQL query with.
+        :type parameters: mapping or iterable
+        """
+        if isinstance(sql, basestring):
+            sql = [sql]
+
+        with closing(self.get_conn()) as conn:
+            if self.supports_autocommit:
+                self.set_autocommit(conn, autocommit)
+
+            for query in sql:
+                self.log.info(query)
+                with closing(conn.execute(query, parameters)) as cur:
+                    self.log.info(cur.row_count)
+            # If autocommit was set to False for db that supports autocommit,
+            # or if db does not supports autocommit, we do a manual commit.
+            if not self.get_autocommit(conn):
+                conn.commit()
+
+    def set_autocommit(self, conn, autocommit):
+        """
+        Sets the autocommit flag on the connection
+
+        :param conn: Connection to set autocommit setting to.
+        :type conn: connection object
+        :param autocommit: The autocommit setting to set.
+        :type autocommit: bool
+        """
+        if not self.supports_autocommit and autocommit:
+            self.log.warning(
+                ("%s connection doesn't support "
+                 "autocommit but autocommit activated."),
+                getattr(self, self.conn_name_attr))
+        conn.set_autocommit(autocommit)
+
+    def get_autocommit(self, conn):
+        """
+        Get autocommit setting for the provided connection.
+        Return True if autocommit is set.
+        Return False if autocommit is not set or set to False or conn
+        does not support autocommit.
+
+        :param conn: Connection to get autocommit setting from.
+        :type conn: connection object
+        :return: connection autocommit setting.
+        :rtype bool
 
 Review comment:
   Thanks! I looked over the file some many times...

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

[GitHub] [airflow] mik-laj commented on a change in pull request #7621: [AIRFLOW-6982] add native python exasol support

Posted by GitBox <gi...@apache.org>.
mik-laj commented on a change in pull request #7621: [AIRFLOW-6982] add native python exasol support
URL: https://github.com/apache/airflow/pull/7621#discussion_r388952345
 
 

 ##########
 File path: airflow/providers/exasol/hooks/exasol.py
 ##########
 @@ -0,0 +1,179 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+from contextlib import closing
+
+import pyexasol
+from past.builtins import basestring
+
+from airflow.hooks.dbapi_hook import DbApiHook
+
+
+class ExasolHook(DbApiHook):
+    """
+    Interact with Exasol.
+    You can specify the pyexasol ``compression``, ``encryption``, ``json_lib``
+    and ``client_name``  parameters in the extra field of your connection
+    as ``{"compression": True, "json_lib": "rapidjson", etc}``.
+    See `pyexasol reference
+    <https://github.com/badoo/pyexasol/blob/master/docs/REFERENCE.md#connect>`_
+    for more details.
+    """
+    conn_name_attr = 'exasol_conn_id'
+    default_conn_name = 'exasol_default'
+    supports_autocommit = True
+
+    def __init__(self, *args, **kwargs):
+        super(ExasolHook, self).__init__(*args, **kwargs)
+        self.schema = kwargs.pop("schema", None)
+
+    def get_conn(self):
+        conn_id = getattr(self, self.conn_name_attr)
+        conn = self.get_connection(conn_id)
+        conn_args = dict(
+            dsn='%s:%s' % (conn.host, conn.port),
+            user=conn.login,
+            password=conn.password,
+            schema=self.schema or conn.schema)
+        # check for parameters in conn.extra
+        for arg_name, arg_val in conn.extra_dejson.items():
+            if arg_name in ['compression', 'encryption', 'json_lib', 'client_name']:
+                conn_args[arg_name] = arg_val
+
+        conn = pyexasol.connect(**conn_args)
+        return conn
+
+    def get_pandas_df(self, sql, parameters=None):
+        """
+        Executes the sql and returns a pandas dataframe
+
+        :param sql: the sql statement to be executed (str) or a list of
+            sql statements to execute
+        :type sql: str or list
+        :param parameters: The parameters to render the SQL query with.
+        :type parameters: mapping or iterable
+        """
+        with closing(self.get_conn()) as conn:
+            conn.export_to_pandas(sql, query_params=parameters)
+
+    def get_records(self, sql, parameters=None):
+        """
+        Executes the sql and returns a set of records.
+
+        :param sql: the sql statement to be executed (str) or a list of
+            sql statements to execute
+        :type sql: str or list
+        :param parameters: The parameters to render the SQL query with.
+        :type parameters: mapping or iterable
+        """
+        with closing(self.get_conn()) as conn:
+            with closing(conn.execute(sql, parameters)) as cur:
+                return cur.fetchall()
+
+    def get_first(self, sql, parameters=None):
+        """
+        Executes the sql and returns the first resulting row.
+
+        :param sql: the sql statement to be executed (str) or a list of
+            sql statements to execute
+        :type sql: str or list
+        :param parameters: The parameters to render the SQL query with.
+        :type parameters: mapping or iterable
+        """
+        with closing(self.get_conn()) as conn:
+            with closing(conn.execute(sql, parameters)) as cur:
+                return cur.fetchone()
+
+    def run(self, sql, autocommit=False, parameters=None):
+        """
+        Runs a command or a list of commands. Pass a list of sql
+        statements to the sql parameter to get them to execute
+        sequentially
+
+        :param sql: the sql statement to be executed (str) or a list of
+            sql statements to execute
+        :type sql: str or list
+        :param autocommit: What to set the connection's autocommit setting to
+            before executing the query.
+        :type autocommit: bool
+        :param parameters: The parameters to render the SQL query with.
+        :type parameters: mapping or iterable
+        """
+        if isinstance(sql, basestring):
+            sql = [sql]
+
+        with closing(self.get_conn()) as conn:
+            if self.supports_autocommit:
+                self.set_autocommit(conn, autocommit)
+
+            for query in sql:
+                self.log.info(query)
+                with closing(conn.execute(query, parameters)) as cur:
+                    self.log.info(cur.row_count)
+            # If autocommit was set to False for db that supports autocommit,
+            # or if db does not supports autocommit, we do a manual commit.
+            if not self.get_autocommit(conn):
+                conn.commit()
+
+    def set_autocommit(self, conn, autocommit):
+        """
+        Sets the autocommit flag on the connection
+
+        :param conn: Connection to set autocommit setting to.
+        :type conn: connection object
+        :param autocommit: The autocommit setting to set.
+        :type autocommit: bool
+        """
+        if not self.supports_autocommit and autocommit:
+            self.log.warning(
+                ("%s connection doesn't support "
+                 "autocommit but autocommit activated."),
+                getattr(self, self.conn_name_attr))
+        conn.set_autocommit(autocommit)
+
+    def get_autocommit(self, conn):
+        """
+        Get autocommit setting for the provided connection.
+        Return True if autocommit is set.
+        Return False if autocommit is not set or set to False or conn
+        does not support autocommit.
+
+        :param conn: Connection to get autocommit setting from.
+        :type conn: connection object
+        :return: connection autocommit setting.
+        :rtype bool
 
 Review comment:
   Do you have IDE? Syntax coloring makes it very easy to find a bug.
   ![Screenshot 2020-03-06 at 16 00 21](https://user-images.githubusercontent.com/12058428/76094857-9ae23980-5fc3-11ea-95c9-8afd1f25bae4.png)
   

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

[GitHub] [airflow] inytar commented on a change in pull request #7621: [AIRFLOW-6982] add native python exasol support

Posted by GitBox <gi...@apache.org>.
inytar commented on a change in pull request #7621: [AIRFLOW-6982] add native python exasol support
URL: https://github.com/apache/airflow/pull/7621#discussion_r388968617
 
 

 ##########
 File path: airflow/providers/exasol/hooks/exasol.py
 ##########
 @@ -0,0 +1,179 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+from contextlib import closing
+
+import pyexasol
+from past.builtins import basestring
+
+from airflow.hooks.dbapi_hook import DbApiHook
+
+
+class ExasolHook(DbApiHook):
+    """
+    Interact with Exasol.
+    You can specify the pyexasol ``compression``, ``encryption``, ``json_lib``
+    and ``client_name``  parameters in the extra field of your connection
+    as ``{"compression": True, "json_lib": "rapidjson", etc}``.
+    See `pyexasol reference
+    <https://github.com/badoo/pyexasol/blob/master/docs/REFERENCE.md#connect>`_
+    for more details.
+    """
+    conn_name_attr = 'exasol_conn_id'
+    default_conn_name = 'exasol_default'
+    supports_autocommit = True
+
+    def __init__(self, *args, **kwargs):
+        super(ExasolHook, self).__init__(*args, **kwargs)
+        self.schema = kwargs.pop("schema", None)
+
+    def get_conn(self):
+        conn_id = getattr(self, self.conn_name_attr)
+        conn = self.get_connection(conn_id)
+        conn_args = dict(
+            dsn='%s:%s' % (conn.host, conn.port),
+            user=conn.login,
+            password=conn.password,
+            schema=self.schema or conn.schema)
+        # check for parameters in conn.extra
+        for arg_name, arg_val in conn.extra_dejson.items():
+            if arg_name in ['compression', 'encryption', 'json_lib', 'client_name']:
+                conn_args[arg_name] = arg_val
+
+        conn = pyexasol.connect(**conn_args)
+        return conn
+
+    def get_pandas_df(self, sql, parameters=None):
+        """
+        Executes the sql and returns a pandas dataframe
+
+        :param sql: the sql statement to be executed (str) or a list of
+            sql statements to execute
+        :type sql: str or list
+        :param parameters: The parameters to render the SQL query with.
+        :type parameters: mapping or iterable
+        """
+        with closing(self.get_conn()) as conn:
+            conn.export_to_pandas(sql, query_params=parameters)
+
+    def get_records(self, sql, parameters=None):
+        """
+        Executes the sql and returns a set of records.
+
+        :param sql: the sql statement to be executed (str) or a list of
+            sql statements to execute
+        :type sql: str or list
+        :param parameters: The parameters to render the SQL query with.
+        :type parameters: mapping or iterable
+        """
+        with closing(self.get_conn()) as conn:
+            with closing(conn.execute(sql, parameters)) as cur:
+                return cur.fetchall()
+
+    def get_first(self, sql, parameters=None):
+        """
+        Executes the sql and returns the first resulting row.
+
+        :param sql: the sql statement to be executed (str) or a list of
+            sql statements to execute
+        :type sql: str or list
+        :param parameters: The parameters to render the SQL query with.
+        :type parameters: mapping or iterable
+        """
+        with closing(self.get_conn()) as conn:
+            with closing(conn.execute(sql, parameters)) as cur:
+                return cur.fetchone()
+
+    def run(self, sql, autocommit=False, parameters=None):
+        """
+        Runs a command or a list of commands. Pass a list of sql
+        statements to the sql parameter to get them to execute
+        sequentially
+
+        :param sql: the sql statement to be executed (str) or a list of
+            sql statements to execute
+        :type sql: str or list
+        :param autocommit: What to set the connection's autocommit setting to
+            before executing the query.
+        :type autocommit: bool
+        :param parameters: The parameters to render the SQL query with.
+        :type parameters: mapping or iterable
+        """
+        if isinstance(sql, basestring):
+            sql = [sql]
+
+        with closing(self.get_conn()) as conn:
+            if self.supports_autocommit:
+                self.set_autocommit(conn, autocommit)
+
+            for query in sql:
+                self.log.info(query)
+                with closing(conn.execute(query, parameters)) as cur:
+                    self.log.info(cur.row_count)
+            # If autocommit was set to False for db that supports autocommit,
+            # or if db does not supports autocommit, we do a manual commit.
+            if not self.get_autocommit(conn):
+                conn.commit()
+
+    def set_autocommit(self, conn, autocommit):
+        """
+        Sets the autocommit flag on the connection
+
+        :param conn: Connection to set autocommit setting to.
+        :type conn: connection object
+        :param autocommit: The autocommit setting to set.
+        :type autocommit: bool
+        """
+        if not self.supports_autocommit and autocommit:
+            self.log.warning(
+                ("%s connection doesn't support "
+                 "autocommit but autocommit activated."),
+                getattr(self, self.conn_name_attr))
+        conn.set_autocommit(autocommit)
+
+    def get_autocommit(self, conn):
+        """
+        Get autocommit setting for the provided connection.
+        Return True if autocommit is set.
+        Return False if autocommit is not set or set to False or conn
+        does not support autocommit.
+
+        :param conn: Connection to get autocommit setting from.
+        :type conn: connection object
+        :return: connection autocommit setting.
+        :rtype bool
 
 Review comment:
   I do, but clearly not one that highlights rst at this level. Something to look into.

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

[GitHub] [airflow] boring-cyborg[bot] commented on issue #7621: [AIRFLOW-6982] add native python exasol support

Posted by GitBox <gi...@apache.org>.
boring-cyborg[bot] commented on issue #7621: [AIRFLOW-6982] add native python exasol support
URL: https://github.com/apache/airflow/pull/7621#issuecomment-608042032
 
 
   Awesome work, congrats on your first merged pull request!
   

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

[GitHub] [airflow] dimberman merged pull request #7621: [AIRFLOW-6982] add native python exasol support

Posted by GitBox <gi...@apache.org>.
dimberman merged pull request #7621: [AIRFLOW-6982] add native python exasol support
URL: https://github.com/apache/airflow/pull/7621
 
 
   

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

[GitHub] [airflow] mik-laj commented on a change in pull request #7621: [AIRFLOW-6982] add native python exasol support

Posted by GitBox <gi...@apache.org>.
mik-laj commented on a change in pull request #7621: [AIRFLOW-6982] add native python exasol support
URL: https://github.com/apache/airflow/pull/7621#discussion_r388920638
 
 

 ##########
 File path: airflow/providers/exasol/hooks/exasol.py
 ##########
 @@ -0,0 +1,179 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+from contextlib import closing
+
+import pyexasol
+from past.builtins import basestring
+
+from airflow.hooks.dbapi_hook import DbApiHook
+
+
+class ExasolHook(DbApiHook):
+    """
+    Interact with Exasol.
+    You can specify the pyexasol ``compression``, ``encryption``, ``json_lib``
+    and ``client_name``  parameters in the extra field of your connection
+    as ``{"compression": True, "json_lib": "rapidjson", etc}``.
+    See `pyexasol reference
+    <https://github.com/badoo/pyexasol/blob/master/docs/REFERENCE.md#connect>`_
+    for more details.
+    """
+    conn_name_attr = 'exasol_conn_id'
+    default_conn_name = 'exasol_default'
+    supports_autocommit = True
+
+    def __init__(self, *args, **kwargs):
+        super(ExasolHook, self).__init__(*args, **kwargs)
+        self.schema = kwargs.pop("schema", None)
+
+    def get_conn(self):
+        conn_id = getattr(self, self.conn_name_attr)
+        conn = self.get_connection(conn_id)
+        conn_args = dict(
+            dsn='%s:%s' % (conn.host, conn.port),
+            user=conn.login,
+            password=conn.password,
+            schema=self.schema or conn.schema)
+        # check for parameters in conn.extra
+        for arg_name, arg_val in conn.extra_dejson.items():
+            if arg_name in ['compression', 'encryption', 'json_lib', 'client_name']:
+                conn_args[arg_name] = arg_val
+
+        conn = pyexasol.connect(**conn_args)
+        return conn
+
+    def get_pandas_df(self, sql, parameters=None):
+        """
+        Executes the sql and returns a pandas dataframe
+
+        :param sql: the sql statement to be executed (str) or a list of
+            sql statements to execute
+        :type sql: str or list
+        :param parameters: The parameters to render the SQL query with.
+        :type parameters: mapping or iterable
+        """
+        with closing(self.get_conn()) as conn:
+            conn.export_to_pandas(sql, query_params=parameters)
+
+    def get_records(self, sql, parameters=None):
+        """
+        Executes the sql and returns a set of records.
+
+        :param sql: the sql statement to be executed (str) or a list of
+            sql statements to execute
+        :type sql: str or list
+        :param parameters: The parameters to render the SQL query with.
+        :type parameters: mapping or iterable
+        """
+        with closing(self.get_conn()) as conn:
+            with closing(conn.execute(sql, parameters)) as cur:
+                return cur.fetchall()
+
+    def get_first(self, sql, parameters=None):
+        """
+        Executes the sql and returns the first resulting row.
+
+        :param sql: the sql statement to be executed (str) or a list of
+            sql statements to execute
+        :type sql: str or list
+        :param parameters: The parameters to render the SQL query with.
+        :type parameters: mapping or iterable
+        """
+        with closing(self.get_conn()) as conn:
+            with closing(conn.execute(sql, parameters)) as cur:
+                return cur.fetchone()
+
+    def run(self, sql, autocommit=False, parameters=None):
+        """
+        Runs a command or a list of commands. Pass a list of sql
+        statements to the sql parameter to get them to execute
+        sequentially
+
+        :param sql: the sql statement to be executed (str) or a list of
+            sql statements to execute
+        :type sql: str or list
+        :param autocommit: What to set the connection's autocommit setting to
+            before executing the query.
+        :type autocommit: bool
+        :param parameters: The parameters to render the SQL query with.
+        :type parameters: mapping or iterable
+        """
+        if isinstance(sql, basestring):
+            sql = [sql]
+
+        with closing(self.get_conn()) as conn:
+            if self.supports_autocommit:
+                self.set_autocommit(conn, autocommit)
+
+            for query in sql:
+                self.log.info(query)
+                with closing(conn.execute(query, parameters)) as cur:
+                    self.log.info(cur.row_count)
+            # If autocommit was set to False for db that supports autocommit,
+            # or if db does not supports autocommit, we do a manual commit.
+            if not self.get_autocommit(conn):
+                conn.commit()
+
+    def set_autocommit(self, conn, autocommit):
+        """
+        Sets the autocommit flag on the connection
+
+        :param conn: Connection to set autocommit setting to.
+        :type conn: connection object
+        :param autocommit: The autocommit setting to set.
+        :type autocommit: bool
+        """
+        if not self.supports_autocommit and autocommit:
+            self.log.warning(
+                ("%s connection doesn't support "
+                 "autocommit but autocommit activated."),
+                getattr(self, self.conn_name_attr))
+        conn.set_autocommit(autocommit)
+
+    def get_autocommit(self, conn):
+        """
+        Get autocommit setting for the provided connection.
+        Return True if autocommit is set.
+        Return False if autocommit is not set or set to False or conn
+        does not support autocommit.
+
+        :param conn: Connection to get autocommit setting from.
+        :type conn: connection object
+        :return: connection autocommit setting.
+        :rtype bool
 
 Review comment:
   ```suggestion
           :rtype: bool
   ```

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

[GitHub] [airflow] mik-laj commented on a change in pull request #7621: [AIRFLOW-6982] add native python exasol support

Posted by GitBox <gi...@apache.org>.
mik-laj commented on a change in pull request #7621: [AIRFLOW-6982] add native python exasol support
URL: https://github.com/apache/airflow/pull/7621#discussion_r387915297
 
 

 ##########
 File path: setup.py
 ##########
 @@ -541,6 +544,7 @@ def do_setup():
             'docker': docker,
             'druid': druid,
             'elasticsearch': elasticsearch,
+            'exasol': exasol,
 
 Review comment:
   Can you also add this package to the documentation?
   https://airflow.readthedocs.io/en/latest/installation.html#extra-packages

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

[GitHub] [airflow] inytar commented on issue #7621: [AIRFLOW-6982] add native python exasol support

Posted by GitBox <gi...@apache.org>.
inytar commented on issue #7621: [AIRFLOW-6982] add native python exasol support
URL: https://github.com/apache/airflow/pull/7621#issuecomment-595756254
 
 
   I've looked into the lint & test issues. I've got Jenkins almost happy, except for one warning in the build-docs. I get the the following message:
   ```
   opt/airflow/docs/_api/airflow/providers/exasol/hooks/exasol/index.rst:122: WARNING: Field list ends without a blank line; unexpected unindent.
   ```
   I'm assuming it has to do with the doc-strings in [`airflow/providers/exasol/hooks/exasol.py`](https://github.com/apache/airflow/pull/7621/files#diff-d4d9616d2fe28929ca431e540d4b86e9), but I can't find what it is. I'd love some input.

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services