incubator-airflow/airflow/hooks/postgres_hook.py

89 строки
3.1 KiB
Python
Исходник Обычный вид История

# -*- coding: utf-8 -*-
#
# 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.
2015-03-04 21:24:23 +03:00
import psycopg2
import psycopg2.extensions
from contextlib import closing
from airflow.hooks.dbapi_hook import DbApiHook
2015-03-04 21:24:23 +03:00
class PostgresHook(DbApiHook):
"""
2015-03-04 21:24:23 +03:00
Interact with Postgres.
You can specify ssl parameters in the extra field of your connection
as ``{"sslmode": "require", "sslcert": "/path/to/cert.pem", etc}``.
Note: For Redshift, use keepalives_idle in the extra connection parameters
and set it to less than 300 seconds.
"""
conn_name_attr = 'postgres_conn_id'
default_conn_name = 'postgres_default'
supports_autocommit = True
def __init__(self, *args, **kwargs):
super(PostgresHook, self).__init__(*args, **kwargs)
self.schema = kwargs.pop("schema", None)
2015-03-04 21:24:23 +03:00
def get_conn(self):
2015-07-24 08:44:32 +03:00
conn = self.get_connection(self.postgres_conn_id)
conn_args = dict(
host=conn.host,
user=conn.login,
password=conn.password,
dbname=self.schema or conn.schema,
port=conn.port)
# check for ssl parameters in conn.extra
for arg_name, arg_val in conn.extra_dejson.items():
if arg_name in ['sslmode', 'sslcert', 'sslkey',
'sslrootcert', 'sslcrl', 'application_name',
'keepalives_idle']:
conn_args[arg_name] = arg_val
[AIRFLOW-2017][Airflow 2017] adding query output to PostgresOperator Make sure you have checked _all_ steps below. ### JIRA - [x] My PR addresses the following [Airflow 2017] (https://issues.apache.org/jira/browse/AIRFLOW-201 7/) issues and references them in the PR title. For example, "[AIRFLOW-2017] My Airflow PR" - https://issues.apache.org/jira/browse/AIRFLOW-2017 ### Description - [x] Here are some details about my PR, including screenshots of any UI changes: Currently we're not getting the output logs of the postgres operator that you would get otherwise if you ran a psql command. It's because the postgres conn has an attribute called [notices](http://init d.org/psycopg/docs/connection.html#connection.noti ces) which contains this information. We need to just print the results of this to get that output in the airflow logs, which makes it easy to debug amongst other things. I've included some images for before and after pictures. **BEFORE** <img width="1146" alt="screen shot 2018-01-19 at 4 46 59 pm" src="https://user-images.githubuserconte nt.com/10408007/35178405-6f6a1da8-fd3d-11e7-8f50-0 dbd567d8ab4.png"> **AFTER** <img width="1147" alt="screen shot 2018-01-19 at 4 46 25 pm" src="https://user-images.githubuserconte nt.com/10408007/35178406-74ea4ae6-fd3d-11e7-9551-6 31eac6bfe7b.png"> ### Tests - [x] My PR adds the following unit tests __OR__ does not need testing for this extremely good reason: There isn't anything to test, there is nothing changing to the current implementation besides an addition of logging. ### Commits - [x] My commits all reference JIRA issues in their subject lines, and I have squashed multiple commits if they address the same issue. In addition, my commits follow the guidelines from "[How to write a good git commit message](http://chris.beams.io/posts/git- commit/)": 1. Subject is separated from body by a blank line 2. Subject is limited to 50 characters 3. Subject does not end with a period 4. Subject uses the imperative mood ("add", not "adding") 5. Body wraps at 72 characters 6. Body explains "what" and "why", not "how" - [x] Passes `git diff upstream/master -u -- "*.py" | flake8 --diff` Closes #2959 from Acehaidrey/AIRFLOW-2017
2018-01-20 12:05:16 +03:00
self.conn = psycopg2.connect(**conn_args)
return self.conn
def copy_expert(self, sql, filename, open=open):
'''
Executes SQL using psycopg2 copy_expert method
Necessary to execute COPY command without access to a superuser
'''
f = open(filename, 'w')
with closing(self.get_conn()) as conn:
with closing(conn.cursor()) as cur:
cur.copy_expert(sql, f)
@staticmethod
def _serialize_cell(cell, conn):
"""
Postgresql will adapt all arguments to the execute() method internally,
hence we return cell without any conversion.
See http://initd.org/psycopg/docs/advanced.html#adapting-new-types for
more information.
:param cell: The cell to insert into the table
:type cell: object
:param conn: The database connection
:type conn: connection object
:return: The cell
:rtype: object
"""
return cell