작성
·
49
0
안녕하세요.
오늘도 Airflow 강의를 듣던 중 에러가 나는 부분이 있어 질문드리고자 합니다 ㅠ
우선 customized 된 Hook의 bulk_load 기능을 사용하는 과정에서 에러가 발생하는데요..
강의에서 알려주신대로 아래와 같이 두 개의 파이썬 파일을 작성해서 DAG을 실행했습니다.
(코드도 GitHub에 올려주신 것과 동일합니다)
plugins/hooks/custom_postgres_hook.py
dags/dags_python_with_custom_hook_bulk_load.py
그런데 DAG 실행 과정에서 아래와 같은 에러가 발생합니다.
(Failure caused by 'Engine' object has no attribute 'cursor')
제가 docker-compose.yaml 파일 내 postgres_custom 서비스를 정의할 때, 5433:5432로 포트 포워딩 해줘서 그런가 싶어서, custom_postgres_hook.py 코드에서 uri 변수에 포트번호를 5432로 같이 부여해줬음에도 동일한 에러가 발생합니다.
무엇이 문제일까요..?
답변 2
0
안녕하세요 Idea님
혹시 몰라 저도 재수행해봤는데 3.0 버전에서도 잘 수행됩니다.
그리고 plugins/hooks/custom_postgres_hooks.py 파일 내용좀 전체 올려보시겠어요?
로그상 그 파일의 49번째 라인에서 오류가 발생한걸로 나오는데 이 파일은 47번째 라인이 끝입니다.
혹시 Idea님이 조금 수정하면서 잘못 수정하셨거나 복붙을 잘못하신게 아닌가 싶어요.
아무튼 이 에러는 파이썬 코드상의 에러이고 포트매핑과는 상관없는 부분입니다.
파일 전체 올려주시거나 github 주소 올려주시면 제가 가서 볼께요!
음 제가 Idea 님 github의 plugins/hooks/custom_postgres_hook.py 파일을 붙여넣고 실행해도 이상없이 잘 실행되네요.
그렇다면 sqlalchemy 버전이 좀 의심되는데 컨테이너 내부로 들어가서 python 명령을 치고 아래 두 패키지 버전 확인 부탁드려요.
>>> import pandas
>>> import sqlalchemy
>>> pandas.__version__
'2.1.4'
>>> sqlalchemy.__version__
'1.4.54'
예전에 다른 수강생 분께서도 동일한 질문을 하신적이 있습니다. 관련해서 찾은 링크가 https://stackoverflow.com/questions/38332787/pandas-to-sql-to-sqlite-returns-engine-object-has-no-attribute-cursor
이거였는데 중요한 게 pandas 라이브러리와 sqlalchemy 라이브러리간의 의존성 문제였습니다. 위 문서에서 찾은 바에 의하면 pandas 라이브러리 버전이 2.2 미만일 때는 지금 작성된 코드가 정상 동작합니다. 그러나 2.2 보다 같거나 클 경우에는
with engine.connect() as conn:
df = pd.read_sql(
sql=query,
con=conn.connection
)
이런 식으로 바꿔줘야 한다는 내용이에요.
일단 버전 먼저 확인 부탁드려요 ^^
안녕하세요 강사님!
버전 확인 결과, 아래와 같이 pandas 버전이 2.2.3, sqlalchemy 버전이 1.4.54로 확인되네요.
말씀하신대로 라이브러리 의존성 문제 같은데, 버전을 낮춰주던지 아니면 connection 코드 부분을 수정하던지 해야 할 것 같아요.
도커 컨테이너 내부에 있는 파이썬 라이브러리 버전을 변경하는 방법과 기존 버전을 그대로 유지한채 connection 부분 코드를 수정하는 방법 2가지에 대해 자세히 설명해주실 수 있을까요?
특히 제가 로컬 환경에서 분석 및 개발만 하다 보니, 도커 컨테이너 내부에 있는 라이브러리 버전을 변경할 때, airflow 관련 모든 컨테이너들에 대해 하나씩 직접 들어가서 버전 업데이트를 해줘야 하는 것인지 궁금합니다.
네 역시 2.2 이상 버전이었네요.
그런데 좀 이상한게 Airflow 최신 버전인 3.0.6 을 설치해도 파이썬 3.12 버전에서 라이브러리 종속성 파일(requirements.txt)를 보면 여전히 pandas 버전은 2.1.4 로 설치되도록 되어 있습니다. 어떻게 2.2.3 버전이 설치가 되었는지 의문이네요.
참고로 requirements.txt 파일은 여기서 볼 수 있습니다.
https://raw.githubusercontent.com/apache/airflow/constraints-3.0.6/constraints-3.12.txt
그리고 말씀하신 pandas 라이브러리 버전을 2.1 버전대로 낮추려면 두 가지 방법이 있는데
(1) airflow base 이미지를 기반으로 pandas 라이브러리 2.1 버전만 변경한 custom 이미지를 하나 만드는 방법
(2) 실행중인 컨테이너 안으로 들어가서 pandas 라이브러리 교체해주는 법
(1)은 영구 반영되는 방법이고 (2)는 컨테이너가 구동중일 때만 유효한 방법입니다.
먼저 (2) 방법이 간단하니까 (2) 방법으로 한번 진행해보시겠어요?
우선 잡을 실제 실행하는 것은 워커 컨테이너니까 워커 컨테이너 안으로 들어가서
pip install --no-cache-dir --upgrade --force-reinstall "pandas>=2.1,<2.2"
이렇게 쳐주세요.
그럼 워커 컨테이너만 pandas 라이브러리 버전 교체됩니다. 혹시 다른 라이브러리와의 충돌때문에 pip install 이 잘 안될 수도 있습니다. 그럼 다시 질문 남겨주세요. pip install 이 잘 됐다면 DAG 다시 수행해보시면 될 것 같아요.
그 다음 pandas==2.2.3 을 유지한 상태에서 코드를 수정하는 방법 알려드릴께요. 연결하는 부분을 아래 코드처럼 바꿔보시겠어요?
engine = create_engine(uri, future=True)
with engine.begin() as conn:
file_df.to_sql(
name=table_name,
con=conn,
schema="public",
if_exists=if_exists,
index=False
)
혹시 안되시면 로그좀 남겨주세요! 제가 확인해볼께요 😀
항상 친절한 답변 감사드립니다 강사님.
말씀하신 2가지 방법으로 진행을 해봤는데, 2가지 경우 모두 에러가 발생합니다...
1) (worker 컨테이너만) pandas 라이브러리 버전 다운
아래와 같이 DAG not found during start up 에러가 출력됩니다.
혹시 몰라서 sudo docker compose down 하고 sudo docker compose up -d 로 실행 후, 다시 worker 컨테이너 내부에서 pandas 라이브러리 버전을 다운시켜서 실행시켜봐도 동일한 에러가 뜨네요 ㅠ 뭐가 문제일까요...
(수동으로 trigger 버튼을 눌러서 실행시켜 줬습니다)g start up
2) pandas 라이브러리 버전 유지 후, python 코드 수정
버전은 유지한 채 코드만 강사님께서 알려주신대로 수정하면, "Failure caused by 'Connection' object has no attribute 'cursor'" 에러 메세지가 출력됩니다.
안녕하세요
음 pandas 라이브러리만 버전 낮추면 numpy랑 충돌이 있나보네요.
혹시 지금 구동중인 airflow 이미지 버전이 어떻게 되나요?
docker-compose.yaml 파일의 image 항목 값좀 적어주실래요?
그리고 pandas=2.2.3 로 버전 올려서 저도 테스트해봤는데 sqlalchemy 와는 계속 충돌이 발생하네요. 아마도 sqlalchemy 버전도 2버전대로 올려야 충돌 해소가 되는듯 합니다.
그래서 해결을 위해 airflow의 이미지를 다시 확인해보고 https://raw.githubusercontent.com/apache/airflow/constraints-3.0.6/constraints-3.12.txt
에 나온대로 의존성을 갖는지 확인해보는 것으로 해야할듯합니다.
앞서 글에서도 남겼지만 위 의존성대로라면 pandas=2.1.4 를 가져야 하는데 왜 2.2.3이 설치됐는지 의문이긴합니다.
우선 airflow 이미지 버전좀 남겨주세요 ^^
안녕하세요 강사님!
우선 docker-compose.yaml 파일 내 image 항목의 경우, 아래와 같이 airflow_custom 으로 작성되어 있고, 초기 docker-compose.yaml 파일에서 다른 container 정보랑 네트워크 정보만 추가된 상태라고 보시면 될 것 같습니다.
그리고 sudo docker images 명령어로 airflow_custom 이미지의 버전을 확인해보니 latest로 나오네요. image 명만 바꿨고, latest라고 뜨는 걸 보니 가장 최신 버전 이미지인 것 같은데...이게 문제가 되는 걸까요?
아 airflow 3.0.3 버전이군요.
참고로 airflow_custom 이미지 빌드할 때 tag 가 latest로 나오는건 tag를 별도 지정해주지 않아서 입니다. 그래서 현재 문제와는 전혀 무관합니다 ^^
airflow 3.0.3 버전 확인해봤는데 이 버전만 pandas==2.2.3 으로 되어 있네요
airflow 3.0.x 버전 모두 확인해봤는데 airflow 3.0.3 만 pandas 라이브러리 버전이 2.2.3 입니다. (airflow==3.0.1/3.0.2/3.0.4/3.0.5/3.0.6 모두 pandas<2.2 입니다)
그래서 죄송하지만, airflow 현재 최신 버전인 airflow 3.0.6 으로 받아서 진행해보시겠어요?
docker-compose.yaml 파일의 image 항목에 apache/airflow:3.0.6 으로 지정하셔서 한번 올려보시면 일단 이 에러는 해결될 것 같아요.
안녕하세요 강사님! 일이 바빠 답변이 늦었습니다 ㅠ
하필 Airflow 3.0.3 버전만 pandas 버전 호환이 안 된 거였다니...ㅠ
그래도 강사님이 답변해주신 덕에 발생한 문제 잘 해결했습니다!
꽤나 긴 시간 동안 대댓글로 자세히 설명해주셨는데, 정말 감사드립니다 :)
0
안녕하세요, 인프런 AI 인턴입니다. Idea님
Airflow를 사용하시면서 발생한 ‘Engine’ 객체의 ‘cursor’ 속성 관련 오류에 대해 고민 중이시군요. 이 문제는 보통 SQLAlchemy 엔진을 사용할 때 발생하는 특이한 상황입니다. 여러분의 문제는 SQLAlchemy의 엔진 객체에는 cursor
메서드가 없다는 점에서 발생합니다. Pandas의 to_sql()
메서드는 SQLAlchemy의 연결 객체를 사용해야 합니다.
SQLAlchemy 연결 사용:
to_sql()
을 사용할 때에는 반드시 SQLAlchemy의 Connectable
객체를 사용해야 합니다. 즉, create_engine()
으로 생성된 엔진을 직접 사용하시길 권장합니다.데이터베이스 URI 확인:
custom_postgres_hook.py
에서 사용되는 데이터베이스 연결 문자열이 정확히 일치하는지 확인하세요. postgresql://user:password@host:port/dbname
형태인지 반드시 재확인해 보시길 바랍니다.버전 확인:
질문에 대한 추가적인 도움이 필요하시면 다음의 유사 답변을 참고하시길 추천드립니다: sqlalchemy.create_engine으로 생성한 객체에 cursor가 없습니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
안녕하세요 강사님.
라인이 넘어간 건 아마도 제가 코드를 따라치면서 제 스타일대로 줄바꿈 및 코드 정리를 하고 주석을 추가를 해서 그런 것 같습니다. (아마도..?)
파이썬 코드가 작성된 깃헙 레포지토리 링크 공유드립니다!
https://github.com/HyeongWookKim/airflow.git
항상 질문에 친절히 답변해주셔서 감사합니다 :)