YandexDirect

04 ноября 2019

Работаем с базой данных Oracle в Python

Доброе время суток.
Давно я ничего не делал на Python, о том как я парсил web страницы на Python можете почитать в статьях Как узнать задолженность за услуги Казахтелекома.Python. Что такое парсер сайтов на примере krisha.kz



Сегодня я хотел бы продемонстрировать работу с БД Oracle в Python. Админ не может жить без автоматизации процессов, а хороший админ пишет для этого программу :-). Благо была задача разблокировки пользователей приложения в некой БД Oracle. Задача сводилась к банальному поиску с помощью sql запроса и дальнейшему update найденных строк. Я это реализовал с помощью Python, для кого-то может это показаться как "стрелять из пушки по воробьям", для меня же это попытка изучить язык программирования.

Итак, для взаимодействия с Oracle я использовал хорошо известную библиотеку cx_oracle, с подробнейшей документацией.

Сначал интерфейс, больше напоминающий интерфейс какого-либо банковского приложения родом из 90-х



Теперь код, основная проблема это многочисленные проверки на ввод неверных данных, конечно в полной мере я его не реализовал, но постарался закрыть наиболее очевидные ошибки при вводе данных.
Теперь расскажу о том, зачем я выкладываю код своих приложений. Когда я сам пишу какое-либо приложение, то с большой вероятностью сталкиваюсь с ошибками синтаксиса, либо логическими ошибками, я соответственно ищу ошибки в Интернете и часто сталкиваюсь с кусками кода, вырванными из контекста. Я же привел весь код, чтобы было понятно как закрывать курсор, как делать commit и как выполнять запросы с помощью cx_oracle.


import cx_Oracle
# функция для подсчета количества строк в выводе

def num_rows(conn, acc_name):

    number_rows = 0

    cursor = conn.cursor()

    cursor.execute('select count(*) from accounts where isdeleted = 1 and upper(active_dir) like upper(:did)',did = '%'+ acc_name + '%')

    result = cursor.fetchone()

    cursor.close

    number_rows = result[0]

    return number_rows

  

# функция печатающая список аккаунтов и заполняющая массив account_id

def print_res(conn, acc_name):

    counter = 1

    arr = []

    cursor = conn.cursor()

    # выводим только записи с признаком удален isdeleted = 1

    cursor.execute('select account_id, first_name, middle_name, last_name, email, active_dir, reason_deleted, position, isdeleted, ip_addr from accounts where isdeleted = 1 and upper(active_dir) like upper(:did)',did = '%'+ acc_name + '%')

    for uname in cursor:

        arr.append (uname[0]) #заполняем массив account_id

        print(counter,  " Values:", uname)

        counter = counter + 1

    return arr

    cursor.close  

# процедура обновления записей в таблицах accounts, staff_accounts

def update_rec(conn, sel_number):

    #print("update_rec started")

    cursor = conn.cursor()

    # выводим только записи с признаком удален isdeleted = 1

    cursor.execute('select account_id, first_name, middle_name, last_name, email, active_dir, reason_deleted, position, ip_addr from accounts where isdeleted = 1 and account_id = :did', did = sel_number)

    row = cursor.fetchone()

    print(row)

    answer = input("Please confirm(yes/no) unlock account_id = " + str(row[0]) + " ")



    if answer == 'yes':

        try:

            cursor.execute('update ACC set ISDELETED = 0 where Id = :did', did = sel_number)      

            cursor.execute('update ACCOUNTS set ISDELETED = 0, reason_deleted = \'\' where ACCOUNT_ID = :did2', did2 = sel_number)

            conn.commit()

            cursor.close()

        except cx_Oracle.IntegrityError as e:

            errorObj, = e.args

            print("-----------------------------")

            print("Error Code:", errorObj.code)

            print("Error Message:", errorObj.message)

        else:

            print("Account unlocked")

    else:

        exit()



def main():

    dsn = """(DESCRIPTION=

             (FAILOVER=on)

             (ADDRESS_LIST=

               (ADDRESS=(PROTOCOL=tcp)(HOST=10.0.0.0)(PORT=1521)))

             (CONNECT_DATA=(SERVICE_NAME=example)))"""



    # Connect as user "hr" with password "welcome" to the "orclpdb1" service running on this computer.

    connection = cx_Oracle.connect("\"account_unlock\"", "Password", dsn, encoding="UTF-8")

    cursor = connection.cursor()

    account_name = input("Print account name: ")



    # если название акаунта пустое то снова вызываем функцию main()

    if account_name == "":

        print("User name empty, enter one more")

        cursor.close

        main()

    else:

     #вызываем функцию num_rows для подсчета и возврата количества строк

        number_rows = num_rows(connection, account_name)

        if number_rows == 0:

            print("Return 0 rows")

            cursor.close

            main()

        if number_rows < 20:

            array = print_res(connection, account_name) # выполняем 2 действия, присваиваем массиву array возвращаемое значение и заодно печатаем список значений

            print(array)

            #print(len(array))

            selected_number = input("Print account_id to unlock: ")

            print(selected_number)

            flag = 0 # переменная флаг для определения попал ли выбранный account_id в массив значений

            for i in range(len(array)):

                #print(array[i])

                if i == len(array):

                    flag = 1

                if str(array[i]) == str(selected_number):

                    print(array[i])

                    update_rec(connection, selected_number) # в функцию передаем connection и выбранный нами account_id

                    exit()



            if flag == 0:     # если не попал то выводим сообщение об ошибке

                print("Wrong account_id. Exit!")

                cursor.close

                main()      

        else:

            print("Result > 20 rows, repeat enter")

            cursor.close

            main()

    connection.close



#блок main

if __name__ == '__main__':

    main()


Спасибо за внимание. Одной из следующих статей по Python планирую написать о том, как я раскручивал youtube страничку, думаю это будет интересно :-)

Комментариев нет:

Отправить комментарий

Общее·количество·просмотров·страницы