복붙노트

[PYTHON] sqlAlchemy를 사용하는 저장 프로 시저

PYTHON

sqlAlchemy를 사용하는 저장 프로 시저

sqlAlchemy를 사용하여 SQL Server의 저장 프로 시저를 호출하려면 어떻게해야합니까?

해결법

  1. ==============================

    1.엔진과 연결에는 임의의 SQL 문에 사용할 수있는 execute () 메서드가 있으며 세션도 마찬가지입니다. 예 :

    엔진과 연결에는 임의의 SQL 문에 사용할 수있는 execute () 메서드가 있으며 세션도 마찬가지입니다. 예 :

    results = sess.execute('myproc ?, ?', [param1, param2])
    

    필요한 경우 outparam ()을 사용하여 출력 매개 변수를 만들거나 bind 매개 변수에 isparam = True 옵션과 함께 bindparam ()을 사용할 수 있습니다.

  2. ==============================

    2.func로 생성 된 프로 시저 객체를 실행하기 만하면됩니다 :

    func로 생성 된 프로 시저 객체를 실행하기 만하면됩니다 :

    from sqlalchemy import create_engine, func
    from sqlalchemy.orm import sessionmaker
    
    engine = create_engine('sqlite://', echo=True)
    print engine.execute(func.upper('abc')).scalar() # Using engine
    session = sessionmaker(bind=engine)()
    print session.execute(func.upper('abc')).scalar() # Using session
    
  3. ==============================

    3.이미 sessionmaker ()로 세션을 만들었다 고 가정하면 다음 함수를 사용할 수 있습니다.

    이미 sessionmaker ()로 세션을 만들었다 고 가정하면 다음 함수를 사용할 수 있습니다.

    def exec_procedure(session, proc_name, params):
        sql_params = ",".join(["@{0}={1}".format(name, value) for name, value in params.items()])
        sql_string = """
            DECLARE @return_value int;
            EXEC    @return_value = [dbo].[{proc_name}] {params};
            SELECT 'Return Value' = @return_value;
        """.format(proc_name=proc_name, params=sql_params)
    
        return session.execute(sql_string).fetchall()
    

    이제 다음과 같은 매개 변수를 사용하여 저장 프로 시저 'MyProc'을 실행할 수 있습니다.

    params = {
        'Foo': foo_value,
        'Bar': bar_value
    }
    exec_procedure(session, 'MyProc', params)
    
  4. ==============================

    4.SQLAlchemy를 사용하여 MySQL에서 저장 프로 시저를 호출하는 가장 쉬운 방법은 Engine.raw_connection ()의 callproc 메소드를 사용하는 것입니다. call_proc에는 호출되는 저장 프로 시저에 필요한 프로 시저 이름 및 매개 변수가 필요합니다.

    SQLAlchemy를 사용하여 MySQL에서 저장 프로 시저를 호출하는 가장 쉬운 방법은 Engine.raw_connection ()의 callproc 메소드를 사용하는 것입니다. call_proc에는 호출되는 저장 프로 시저에 필요한 프로 시저 이름 및 매개 변수가 필요합니다.

    def call_procedure(function_name, params):
           connection = cloudsql.Engine.raw_connection()
           try:
               cursor = connection.cursor()
               cursor.callproc(function_name, params)
               results = list(cursor.fetchall())
               cursor.close()
               connection.commit()
               return results
           finally:
               connection.close()
    
  5. ==============================

    5.문맥 : 나는 flask-sqlalchemy를 MySQL과 ORM 매핑없이 사용한다. 일반적으로 다음을 사용합니다.

    문맥 : 나는 flask-sqlalchemy를 MySQL과 ORM 매핑없이 사용한다. 일반적으로 다음을 사용합니다.

    # in the init method
    _db = SqlAlchemy(app)
    
    #... somewhere in my code ...
    _db.session.execute(query)
    

    저장 프로 시저를 호출하는 것은 기본적으로 지원되지 않습니다. callproc은 일반적인 것이 아니고 mysql 커넥터에만 해당됩니다.

    out 매개 변수가없는 저장 프로 시저의 경우 다음과 같은 쿼리를 실행할 수 있습니다.

    _db.session.execute(sqlalchemy.text("CALL my_proc(:param)"), param='something')
    

    평소처럼 params가있을 때 상황이 더 복잡해집니다.

    params를 사용하는 한 가지 방법은 engine.raw_connection ()을 통해 기본 커넥터에 액세스하는 것입니다. 예 :

    conn = _db.engine.raw_connection()
    # do the call. The actual parameter does not matter, could be ['lala'] as well
    results = conn.cursor().callproc('my_proc_with_one_out_param', [0])
    conn.close()   # commit
    print(results) # will print (<out param result>)
    

    이것은 out 매개 변수에 액세스 할 수 있기 때문에 좋습니다. 그러나이 연결은 플라스크 세션에 의해 관리되지 않습니다. 이는 다른 관리 쿼리와 같이 커밋되거나 중단되지 않는다는 것을 의미합니다 (프로 시저에 부작용이있는 경우에만 문제가 발생 함).

    마지막으로, 나는 이것을 끝내었다.

    # do the call and store the result in a local mysql variabl
    # the name does not matter, as long as it is prefixed by @
    _db.session.execute('CALL my_proc_with_one_out_param(@out)')
    # do another query to get back the result
    result = _db.session.execute('SELECT @out').fetchone()
    

    결과는 하나의 값을 갖는 튜플 인 out 매개 변수가됩니다. 이것은 이상적은 아니지만 가장 위험하지는 않습니다. 세션 중에 다른 쿼리가 실패하면 프로 시저 호출도 중단됩니다 (롤백).

  6. ==============================

    6.내 프로젝트에 대한 절실한 필요성 때문에 Stored Procedure 호출을 처리하는 함수를 작성했습니다.

    내 프로젝트에 대한 절실한 필요성 때문에 Stored Procedure 호출을 처리하는 함수를 작성했습니다.

    여기 있습니다 :

    import sqlalchemy as sql
    
    def execute_db_store_procedure(database, types, sql_store_procedure, *sp_args):
        """ Execute the store procedure and return the response table.
    
        Attention: No injection checking!!!
    
        Does work with the CALL syntax as of yet (TODO: other databases).
    
        Attributes:
            database            -- the database
            types               -- tuple of strings of SQLAlchemy type names.
                                   Each type describes the type of the argument
                                   with the same number.
                                   List: http://docs.sqlalchemy.org/en/rel_0_7/core/types.html
            sql_store_procudure -- string of the stored procedure to be executed
            sp_args             -- arguments passed to the stored procedure
        """
        if not len(types) == len(sp_args):
            raise ValueError("types tuple must be the length of the sp args.")
    
        # Construch the type list for the given types
        # See
        # http://docs.sqlalchemy.org/en/latest/core/sqlelement.html?highlight=expression.text#sqlalchemy.sql.expression.text
        # sp_args (and their types) are numbered from 0 to len(sp_args)-1
        type_list = [sql.sql.expression.bindparam(
                        str(no), type_=getattr(sql.types, typ)())
                            for no, typ in zip(range(len(types)), types)]
    
        try:
            # Adapts to the number of arguments given to the function
            sp_call = sql.text("CALL `%s`(%s)" % (
                    sql_store_procedure,
                    ", ".join([":%s" % n for n in range(len(sp_args))])),
                bindparams=type_list
            )
            #raise ValueError("%s\n%s" % (sp_call, type_list))
            with database.engine.begin() as connection:
                return connection.execute(
                    sp_call,
                    # Don't do this at home, kids...
                    **dict((str(no), arg)
                        for (no, arg) in zip(range(len(sp_args)), sp_args)))
        except sql.exc.DatabaseError:
            raise
    

    이것은 CALL 구문과 함께 작동하므로 MySQL은 예상대로 작동해야합니다. MSSQL은 호출 대신 EXEC를 사용하고 약간 다른 구문을 사용합니다. 따라서 서버에 무관심하게 만드는 것은 당신에게 달려 있지만 너무 어려워서는 안됩니다.

  7. from https://stackoverflow.com/questions/3563738/stored-procedures-with-sqlalchemy by cc-by-sa and MIT license