Viya 4 에서 Python 을 쓰는 길은 두 갈래다. SAS 코드 안에서 PROC PYTHON 으로 파이썬 블록을 실행하는 방식과, 파이썬 쪽에서 SWAT 라이브러리로 CAS 에 직접 붙는 방식이다. 앞의 것은 Compute 세션의 파이썬 런타임을 쓰고, 뒤의 것은 CAS 바이너리 포트(기본 5570)로 붙는다. 연동이 됐는지 확인할 때는 이 둘을 갈라서 봐야 어디가 막혔는지 알 수 있다.
proc python;
submit;
import sys
print(sys.version)
print(sys.executable)
endsubmit;
run;
여기서 실패하면 Launcher·Compute 의 파이썬 설정이나 sas-pyconfig 쪽 문제다. 폐쇄망 구성이라면 SAS Viya 4 폐쇄망 Python 구성 을 먼저 본다.
proc python;
submit;
import importlib.metadata as md
for d in sorted(md.distributions(), key=lambda x: x.metadata["Name"] or ""):
print(d.metadata["Name"], d.version)
endsubmit;
run;
pip list 를 셸로 부르는 방식은 XCMD 가 막혀 있으면 동작하지 않는다. 위처럼 파이썬 표준 라이브러리로 읽는 편이 확실하다.
import swat
conn = swat.CAS(
"controller.sas-cas-server-default.<namespace>.svc.cluster.local",
5570,
"${CAS_USER}",
"${CAS_PASSWORD}",
)
print(conn.serverstatus())
여기서 실패하면 CAS 컨트롤러가 떠 있지 않거나, 인증 토큰·TLS 설정이 어긋난 것이다. 자격 증명을 코드에 적지 말고 ~/.authinfo 또는 환경 변수로 넘긴다.
tbl = conn.CASTable("sales", caslib="casuser")
print(tbl.head())
여기까지 통과하면 연동 자체는 정상이고, 그다음부터는 자원과 성능 문제다.
| 방법 | 쓰는 상황 | 주의 |
|---|---|---|
conn.upload_frame(df, ...) |
작은 데이터, 교육·데모 | 클라이언트에서 임시 파일을 만든다. 임시 경로에 공간·권한이 없으면 실패한다 |
conn.table.loadTable(caslib=..., path=...) |
파일이 CAS 가 볼 수 있는 경로에 있을 때 | CAS 파드에도 같은 경로가 마운트돼 있어야 한다 |
| 외부 DB 를 caslib 으로 붙여 직접 적재 | 운영 | 드라이버와 접속 정보가 CAS 쪽에 있어야 한다 |
경로를 잡을 때 헷갈리는 지점이 있다. SAS Studio 의 왼쪽 파일 창에 올린 파일은 로그인 계정의 홈(/home/<계정>/) 에 들어간다. /opt/sas/sasdata/... 같은 공유 경로에 올렸다면 그 경로를 그대로 쓴다. FileNotFoundError 가 나면 파일이 어느 쪽에 있는지부터 확인한다.
import os
print(os.getcwd())
print(os.listdir("/home/<계정>"))
upload_frame() 은 DataFrame 을 일단 임시 파일로 떨군 뒤 전송한다. 컨테이너의 기본 임시 경로가 작거나 읽기 전용이면 여기서 깨진다.
중요한 것은 TMPDIR 을 import swat 보다 먼저 잡아야 한다는 점이다. 파이썬의 tempfile 모듈은 처음 쓰일 때 임시 경로를 결정하고 캐시하므로, 연결 객체를 만든 뒤에 환경 변수를 바꿔도 이미 늦다.
import os
os.environ["TMPDIR"] = "/opt/sas/sasdata/<계정>" # 쓰기 가능하고 여유 있는 경로
import tempfile, shutil
print("tempdir:", tempfile.gettempdir())
print("free:", shutil.disk_usage(tempfile.gettempdir()).free)
import swat
더 확실한 길은 업로드를 아예 건너뛰고 CAS 가 파일을 직접 읽게 하는 것이다.
try:
conn.addcaslib(
name="sasdata",
path="/opt/sas/sasdata",
subdirs=True,
datasource={"srctype": "path"},
)
except Exception as e:
print("addcaslib skip:", e)
conn.table.loadTable(
caslib="sasdata",
path="<계정>/prog/sales.csv",
casout={"name": "sales", "replace": True},
)
print(conn.table.tableInfo())
addcaslib 의 path 는 CAS 파드 기준 경로다. Compute 파드에서는 보이는데 CAS 파드에는 마운트되지 않은 경로를 적으면 caslib 은 만들어져도 적재가 실패한다.
CAS 액션셋으로 학습까지 파이썬 안에서 끝낼 수 있다.
conn.loadActionSet("decisionTree")
result = conn.decisionTree.dtreeTrain(
table={"name": "sales", "caslib": "casuser"},
target="<타겟컬럼>",
inputs=["<입력컬럼1>", "<입력컬럼2>"],
casOut={"name": "sales_model", "replace": True},
)
print(result)
여기까지는 CAS 안에서만 사는 모델이다. 등록·버전 관리·배포로 이어지는 절차는 SAS Viya 4 모델 개발과 MLOps 에 있다.
iris 인 채로 남는다. 적재한 테이블 이름과 학습 코드의 테이블 이름을 맞춘다.swat.CAS() 를 인자 없이 부르면 환경 변수(CAS_HOST·CAS_PORT 등)에 기댄다. 환경 변수가 없는 세션에서는 호스트·포트를 명시한다.~/.authinfo 파일 권한은 600 이어야 한다.