레코드를 테이블 person
에 삽입하는 함수를 작성했습니다. 행 ID는 내가 SQL select * from add_person('xxx', '[email protected]', 1, 3, '{1,2}')
이 기능을 실행하면 성공적으로 레코드를 삽입 (자동 증가)Postgres 함수를 호출하여 레코드를 삽입 할 때 커밋하는 방법
CREATE OR REPLACE FUNCTION public.add_person(
name character varying,
email character varying,
level integer,
company_id integer,
comp_list integer[])
RETURNS integer as
$BODY$
declare
p_id integer;
begin
insert into person (name, email, level, company_id, comp_list, status, insert_ts) values ($1, $2, $3, $4, $5, 'Y', now())
returning person.person_id into p_id;
return p_id;
end
$BODY$ LANGUAGE 'plpgsql'
시리얼입니다. 그러나 SQLAlchemy를 사용하여 파이썬에서이 함수를 호출하면 레코드를 삽입 할 수 없습니다. 파이썬으로 구성
engine = create_engine(URL(**settings.DATABASE))
session = scoped_session(sessionmaker(bind=engine))
email = '[email protected]'
company = 1
level = 3
comp_list = '1,2'
args = "'', '" + email + "', " + str(company) + ", " + str(level) + ", '{" + comp_list + "}'"
statement = "select * from add_person({})".format(args)
session.execute(statement)
성명은 정확하게 내가 포스트 그레스에서 실행되는 명령과 동일합니다. 그러나 그것은 그것이 예정되어있는 것처럼 테이블에 레코드를 삽입하지 않았습니다. 오류 메시지가 전혀 없습니다. 다른 모든 select
쿼리가 작동하기 때문에 session
, engine
이 올바르게 구성되었습니다.
파이썬 코드를 사용하여 레코드를 삽입 할 수없는 경우에도주의를 기울였습니다. 기본 키의 순서가 증가했습니다. 포스트 그레스에서 함수를 다시 실행할 때 행 ID가 건너 뛰었 기 때문입니다.
커밋하지 않고 SQLAlchemy 세션을 삽입하면 동작이 동일합니다.
def add_person(name, email, company, level, comp_list):
current_ts = datetime.datetime.now()
p = Person(name = name,
email = email,
company_id = company,
level = level,
comp_list = comp_list,
status = 'Y',
insert_ts = current_ts)
session.add(p)
session.flush()
return p.person_id
내가 파이썬 위의 방법, person_id
단위를 실행하지만 레코드가 삽입되지 않은 경우. session.flush
을 다음으로 변경 한 경우에만 레코드가 올바르게 삽입됩니다.
session.add(p)
session.commit()
session.refresh(p)
print(p.person_id)
return p.person_id
plsql 함수를 호출 할 때 삽입을 커밋하는 올바른 방법은 무엇입니까?
[트랜잭션 제어]를 참조하십시오. (http://initd.org/psycopg/docs/usage.html#transactions-control) – klin
값을 전달할 때 문자열 형식을 사용하지 마십시오. * 검색어로 이것이 placeholder/bindparams가하는 것입니다. "how"에 대해서는 http://docs.sqlalchemy.org/en/latest/core/tutorial.html#using-textual-sql을 읽고 "why"에 대해서는 https://xkcd.com/327/을 읽으십시오. –
여기에 텍스트 SQL이 필요하지 않습니다. 함수 제네릭을 사용하면'execute (func.add_person ('', email, company, level, comp_list.split (',')). select())'를 할 수 있습니다. comp_list를 그냥리스트로 전달할 수도 있고 전달해야 할 수도 있습니다. –