Django Raw SQL Query с использованием нескольких баз данных

Я пытаюсь получить информацию из двух разных баз данных в одном запросе.

Ниже приведен пример кода, который я пытаюсь использовать с идентификационной информацией, замененной на общие имена.

У меня мои базы данных настроены следующим образом:

DATABASES = {
 'default': {},
 'primary': {
     'ENGINE': 'django.db.backends.oracle',
     'NAME': 'oracle.test.com:5432/erp',
     'USER':'test1',
     'PASSWORD':'',
 },
 'secondary': {
     'ENGINE': 'django.db.backends.oracle',
     'NAME': 'oracle2.test.com:5432/wms',
     'USER':'test2',
     'PASSWORD':'',
 },
}

Тогда в моих представлениях я имею следующее:

def index(request):
    sql_query = ('select \n'
             '  primary.table1.organization_id "Org", \n'
             '  primary.table2.LOCATION "Loc", \n'
             '  primary.table3.inventory "Inv", \n'
             '  primary.table4.reorder_date "Reorder", \n'
             '  secondary.table3.COMMENTS "Comments", \n'
             'from \n'
               '  primary.table2, primary.table1\n'
               '  LEFT OUTER JOIN primary.table3 On\n'
               '    (primary.table1.SCHEDULE_NUMBER = primary.table3.SCHEDULE_NUMBER) \n'
               '  LEFT OUTER JOIN primary.table4 On \n'
               '    (primary.table1.SCHEDULE_NUMBER = primary.table4.PARENT_SCHEDULE_NUMBER) \n'
               '  LEFT OUTER JOIN secondary.table1 On \n'
               '    (primary.table1.SCHEDULE_NUMBER = primary.table1.SCHEDULE_NUMBER) \n'
             'where
               'primary.table1.item_id = primary.table2.inventory_item and \n'
               'primary.table1.organization_id = primary.table2.organization_id \n')
    with connections['primary', 'secondary'].cursor() as cursor:
        cursor.execute(sql_query)
        field_names = [tuple(x[0] for x in cursor.description)]
        row = cursor.fetchall()
        result = field_names + row
        df = pd.DataFrame(result)
        df.rename(columns=df.iloc[0], inplace=True)
        df.drop([0], inplace=True)
        table = df.to_html(index=False, classes='mystyle', justify='left')
    return render(request, 'template.html', {'table': table})

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

Во-первых, connections является диктой, поэтому вы должны выполнить итерацию по его ключам, чтобы получить оба соединения:

dbs_to_connect = ['primary','secondary']
for k in dbs:
    with connections[k].cursor() as cursor:
        # code here...

Во-вторых, я не уверен, как настроены ваши базы данных и схемы в Oracle, но помните, что запрос всегда должен быть select <colums> from <schema>.<table>. Независимо от этого, строка запроса должна выполняться непосредственно в другом программном обеспечении БД, так что вы можете протестировать ее там, чтобы убедиться, что проблема не в самом запросе.

Основываясь на некоторых советах с других форумов. Я узнал, что невозможно объединить таблицы в разных базах данных. Поэтому вот мое решение. Запустите 2 базы данных как 2 разных запроса, а затем сохраните их результаты в отдельных фреймах данных. Затем используйте pandas merge для объединения этих двух баз данных вместе с помощью левого объединения.

    Filepath = 'example filepath'
    SQL_Query1 = 'example'
    SQL_Query2 = 'example'
    with connections['primary'].cursor() as cursor:
        cursor.execute(SQL_Query1)
        field_names = [tuple(x[0] for x in cursor.description)]
        row = cursor.fetchall()
        result = field_names + row
        df = pd.DataFrame(result)
        df.rename(columns=df.iloc[0], inplace=True)
        df.drop([0], inplace=True)
        df['SCHED_#'] = pd.to_numeric(df['SCHED_#'])

    with connections['secondary'].cursor() as cursor2:
        cursor2.execute(SQL_Query2)
        wms_field_names = [tuple(x[0] for x in cursor2.description)]
        wms_row = cursor2.fetchall()
        wms_result = wms_field_names + wms_row
        wms_df = pd.DataFrame(wms_result)
        wms_df.rename(columns=wms_df.iloc[0], inplace=True)
        wms_df.drop([0], inplace=True)
        wms_df['SCHED_#'] = pd.to_numeric(wms_df['SCHED_#'])

    merged_df = pd.merge(df, wms_df, on='SCHED_#', how='left', indicator=True)
    merged_df.to_csv(filepath, index=False)

Спасибо всем за ваш вклад

Вернуться на верх