import os
from dotenv import load_dotenv
from supabase import create_client
# .env 파일의 환경변수 로드
load_dotenv()
url = os.getenv("SUPABASE_URL")
key = os.getenv("SUPABASE_PUBLISHABLE_KEY")
# Client 초기화
# supabase 클라이언트 객체 생성
supabase = create_client(url, key)
print(supabase)
# <supabase._sync.client.Client object at 0x10d2cc440>
# 사용자 추가
response = supabase.table('users').insert({"email" : "user03@test.org"}).execute()
# documents INSERT
response = supabase.table('documents').insert({
'title' : '첫 번째 문서',
'content' : '본문 내용',
'user_id' : '1320f352-13eb-44fc-8662-3ae945e616cd'
}).execute()
# 회원 목록 조회
response = supabase.table('users').select('*').execute()
response.data
# ilike : 대소문자 구분없이 like문 실행
response = (supabase.table('users')
.select('*')
.ilike('email', 'user02%')
.execute()
)
# single Keyword
response = (supabase.table('users')
.select('*')
.ilike('email', 'user04%')
.single() # 레코드 한 개, 딕셔너리 형태로 반환
# single 키워드 사용시에 레코드가 없거나, 1개 이상 존재하는 경우에 APIERROR 발생
.execute()
)
response.data # API ERROR
# maybe_single Keyword
response = (supabase.table('users')
.select('*')
.ilike('email', 'user04%')
.maybe_single() # 레코드가 0 ~ 1 일 때 사용, 레코드가 없다고 예외 발생 안함
.execute()
)
response.data # None
# LIMIT Keyword
response = (supabase.table('users')
.select('*')
.ilike('email', 'user%')
.limit(1) # like문을 사용할 떄 여러개의 레코드를 출력하면,
#오류가 발생하므로 LIMIT 키워드를 이용해서 강제로 1개의 레코드만 출력
.single()
.execute()
)
response.data
# {'id': 'e8057300-87a3-43e2-aee6-e4b0d817d0b2',
# 'email': 'user01@test.org',
# 'created_at': '2026-09-08T03:00:44.799562'}
# OFFSET Keyword
response = (supabase.table('users')
.select('*')
.ilike('email', 'user%')
.limit(1)
.offset(1) # 1 인덱스에서 1개 조회
.single()
.execute()
)
response.data
# {'id': 'bd0f1b0d-5921-4751-9235-3e21dfb722ef',
# 'email': 'user02@test.org',
# 'created_at': '2026-09-09T00:42:22.44246'}
# ORDER BY Keyword
response =(
supabase.table('users')
.select('*')
.order('email', desc=True) # email 컬럼 기준, 내림차순 정렬
.execute()
)
response.data
# JOIN Keyword
## LEFT JOIN
response = (
supabase.table('documents')
.select('id, title, content, users(id, email)')
.execute()
)
response.data
## INNER JOIN(!inner)
response = (
supabase.table('documents')
.select('id, title, content, users!inner(id, email)')
.execute()
)
response.data
# join table 조건 걸기
response = (
supabase.table('documents')
.select('id, title, content, users!inner(id, email)')
.ilike('users.email', 'user%')
.execute()
)
response.data
# UPDATE Keyword
response = (
supabase.table('documents')
.update({
'title' : '첫 번째 문서(수정)'
})
.eq('id', 'd865df61-ecaa-4117-90e0-84d5a3726118')
.execute()
)
# DELETE Keyword
response = (
supabase.table('users')
.delete()
.eq('id', 'e8057300-87a3-43e2-aee6-e4b0d817d0b2')
.execute()
)
key = os.getenv('SUPABASE_ANON_KEY')
supabase = create_client(url, key)
"""
supabase.auth : 인증(로그인) / 인가(접근 권한) 관련 메서드를 가지고 있는 객체
테이블 명 : auth.users
"""
# 회원가입
response = supabase.auth.sign_up({
'email' : 'user01@test.org',
'password' : 'password1234',
'phone' : '010-1000-1000'
})
# 로그인
response = supabase.auth.sign_in_with_password({
'email' : 'user01@test.org',
'password' : 'password1234'
})
response.user
# 현재 로그인된 사용자 확인
user = supabase.auth.get_user() # 현재 로그인한 사용자 정보, 있으면 로그인, None이면 미 인증 상태
if user:
print(f'로그인 상태 : {user}')
else :
print(f' 미 로그인 상태 ')
# 로그아웃
supabase.auth.sign_out()
순수 API 직접 호출의 한계
장점
프롬프트 | 모델 | 파서 형태로 파이프 기호를 통해 데이터 흐름을 한눈에 파악 가능from langchain_ollama import ChatOllama
from langchain_core.prompts import ChatPromptTemplate
# system : 역할, 상황, 제한 조건, 예시 -> 시스템 메세지, SystemMessage(..)
# user : 사용자의 질의 / HumanMessage(..)
# asistant : AI 답변 / AIMessage(..)
# 시스템에게 역할, 상황, 제한 조건, 예시 등 제시
prompt_template = ChatPromptTemplate.from_messages([
('system', "당신은 컴퓨터 기초 개념을 일상적인 사물에 빗대어 설명하는 교육 전문가입니다. 2문장 이내로 친절하게 설명하세요."),
('user', '{user_question}')
])
# 샘플 프롬프트 선언
sample_prompt = prompt_template.invoke({
"user_question" : "프로그래밍에서 '변수'가 무엇인가요?"
})
# 모델 호출
model = ChatOllama(
model='mistral',
)
# 모델에 샘플 프롬프트 삽입
response = model.invoke(sample_prompt)
# 순수 텍스트만 추출하기
from langchain_core.output_parsers import StrOutputParser
parser = StrOutputParser()
text = parser.invoke(response)
# 파이프 연산자를 사용해서 3개의 컴포넌트를 하나의 파이프라인으로 연결
chain = prompt_template | model | parser
res = chain.invoke({
"user_question" : "'클래스'가 뭔데'"
})
res