在气流dag中添加路径变量时,重复键值违反唯一约束

时间:2018-03-30 21:06:19

标签: airflow

要在气流中设置连接和变量我使用DAG,我们这样做是为了快速设置气流,以防我们必须快速重新设置所有内容。它确实有效,我的连接和变量显示但任务“失败”。错误是说已经存在sql_path变量

[2018-03-30 19:42:48,784] {{models.py:1595}} ERROR - (psycopg2.IntegrityError) duplicate key value violates unique constraint "variable_key_key"
DETAIL:  Key (key)=(sql_path) already exists.
 [SQL: 'INSERT INTO variable (key, val, is_encrypted) VALUES (%(key)s, %(val)s, %(is_encrypted)s) RETURNING variable.id'] [parameters: {'key': 'sql_path', 'val': 'gAAAAABavpM46rWjISLZRRKu4hJRD7HFKMuXMpmJ5Z3DyhFbFOQ91cD9NsQsYyFof_pdPn116d6yNoNoOAqx_LRqMahjbYKUqrhNRiYru4juPv4JEGAv2d0=', 'is_encrypted': True}] (Background on this error at: http://sqlalche.me/e/gkpj)
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1193, in _execute_context
    context)
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/engine/default.py", line 507, in do_execute
    cursor.execute(statement, parameters)
psycopg2.IntegrityError: duplicate key value violates unique constraint "variable_key_key"
DETAIL:  Key (key)=(sql_path) already exists.

但是我检查过,在运行DAG之前,addhoc查询SELECT * FROM variable没有返回任何内容,然后返回我的两个变量。

我检查过我没有两次创建变量,但我不这么认为。 在这里,您可以看到创建路径变量的dag部分

import airflow
from datetime import datetime, timedelta
from airflow.operators.python_operator import PythonOperator
from airflow import models
from airflow.settings import Session
import logging


args = {
    'owner': 'airflow',
    'start_date': airflow.utils.dates.days_ago(1),
    'provide_context': True
}


def init_staging_airflow():
    logging.info('Creating connections, pool and sql path')

    session = Session()

    new_var = models.Variable()
    new_var.key = "sql_path"
    new_var.set_val("/usr/local/airflow/sql")
    session.add(new_var)
    session.commit()

    new_var = models.Variable()
    new_var.key = "conf_path"
    new_var.set_val("/usr/local/airflow/conf")
    session.add(new_var)
    session.commit()

    session.add(new_pool)
    session.commit()

    session.close()

dag = airflow.DAG(
    'init_staging_airflow',
    schedule_interval="@once",
    default_args=args,
    max_active_runs=1)

t1 = PythonOperator(task_id='init_staging_airflow',
                    python_callable=init_staging_airflow,
                    provide_context=False,
                    dag=dag)

3 个答案:

答案 0 :(得分:2)

尝试在DAG中执行Variable.set()时遇到了同样的问题。我相信调度程序会不断轮询DagBag以动态刷新任何更改。这就是为什么在运行网络服务器时看到大量这些内容的原因:

[2018-04-02 11:28:41,531] [45914] {models.py:168} INFO - Filling up the DagBag from /Users/jasontang/XXX/data-server/dags

迟早你会遇到关键约束: enter image description here

我所做的是将我需要在运行时设置的所有变量设置为全局字典(" VARIABLE_DICT"在下面的示例中),并且只允许我的所有DAG和子DAG访问它

def initialize(dag_run_obj):
    global VARIABLE_DICT
    if dag_run_obj.external_trigger:
        VARIABLE_DICT.update(dag_run_obj.conf)
        values = (dag_run_obj.conf['client'],
                  dag_run_obj.conf['vertical'],
                  dag_run_obj.conf['frequency'],
                  dag_run_obj.conf.get('snapshot'))
        config_file = '{0}-{1}/{0}-{1}-{2}.json'.format(*values)
        path = os.path.join(Variable.get('repo_root'), 'conf', config_file)
        VARIABLE_DICT.update(read_config(path))

您可以忽略dag_run_obj部分,因为我专门查找在创建DAG Run时提供给DAG Run的任何其他配置值。在您的其他DAG和subDAG中,只需导入字典。

答案 1 :(得分:0)

justang是正确的,发生这种情况的原因是因为调度程序每次运行调度程序时都会执行dag(调度程序经常运行以检查DAG是否已更改,是否需要启动等)。

答案 2 :(得分:0)

我通过每次在Variable.delete()之前致电Variable.set()来解决此问题。