создание и добавление в список в таблице базы данных SQLAlchemy - PullRequest
0 голосов
/ 18 сентября 2018

Я изучаю SQLAlchemy, и я застрял.У меня есть таблица SQL (table1), имеет два поля: 'name' и 'other_names'

У меня есть файл Excel с двумя столбцами:

first_name alias   
paul   patrick
john   joe
simon  simone
john   joey
john   jo

Я хочу прочитать файл Excelв мою таблицу1, чтобы это выглядело следующим образом (т.е. все псевдонимы для одной строки находятся в одном ряду):

paul    patrick
john    joe,joey,jo
simon   simone

Это идея, которую я пытался реализовать.Код (с комментариями), который я пробовал:

for line in open('file.txt', 'r'): #for each line in the excel file
        line = line.strip().split('\t') #split each line with a name and alias
        first_name = line[0] #first name is the name before the tab
        alias = line[1] #alias is the name after the tab
        instance = 
        Session.query(session,tbs['table1'].name).filter_by(name=first_name) #look through the database table, by name field, and see if the first name is there 
        list_instance = [x[0] for x in instance] #make a list of first names already in database table
        if first_name not in list_instance: #if the excel first name is not in the database table
              alias_list = [] #make an empty list
              alias_list.append(alias) #append the alias
              name_obj = lib.get_or_create( #small function to make db object
              session,
              tbs["table1"],
              name = first_name, #add first name to the name field
              other_names = alias_list # add alias list to the other_names field
            )


       elif first_name in list_instance: #elif first name already in db
             alias_list.append(alias) #append the alias to the alias list made above
             name_obj = lib.get_or_create(
             session,
             tbs["table1"],
             name = first_name,
             other_names = alias_list #create object as before, but use updated alias list
    )

Проблема в том, что я могу заставить приведенный выше код работать без ошибок, но также вывод не является приложенным списком, это просто база данныхтаблица, которая выглядит как файл Excel;то есть

name   alias
paul   patrick
john   joe
simon  simone
john   joey
john   jo

Может кто-нибудь указать, где я иду не так, в частности, как я могу изменить этот код?Пожалуйста, дайте мне знать, если вопрос неясен, я попытался сделать это простым примером.В частности, как мне инициализировать и добавить в списки в качестве записи поля в таблице базы данных SQLalchemy.

Обновление 1: я обновил свой код в соответствии с предложением, приведенным ниже.Однако у меня все еще есть проблема.Это полная цель, код и тестовый файл: Цель:

У меня есть таблица в базе данных (см. Ниже тестовый файл, входящий в таблицу). Таблица имеет два поля: имя (латинское имя, например,homo sapiens) и другие имена (общие названия, например, человек, человек).Я хочу обновить поле (другие имена) в таблице, поэтому вместо:

Rana rugosa human   
Rana rugosa man 
Rana rugosa frog    
Rana rugosa cow

у меня есть:

Rana rugosa human,man,frog,cow

Файл test_data выглядит следующим образом:

origin_organism        common_name         tested_organism
Rana rugosa            human                -
Rana rugosa            man                  -
Rana rugosa            frog                 homo sapiens
Rana rugosa            cow                  Rana rugosa
Rana rugosa            frog                 Rana rugosa
Rana rugosa            frog                 -
Rana rugosa            frog                 -
Rana rugosa            frog                homo sapiens
-                      -                   -
-                      -                   homo sapiens
-                      -                   -
-                      -                   -
-                      -                   -
-                      -                   -
streptococcus pneumoniae    -              -

Код:

import sys 
from sqlalchemy.orm  import * 
from sqlalchemy  import * 
from dbn.sqlalchemy_module  import lib 
import pd

engine = lib.get_engine(user="user", psw="pwd", db="db", db_host="111.111.111.11")
Base = lib.get_automapped_base(engine)
session = Session(engine)
tbs = lib.get_mapped_classes(Base)
session.rollback()
df = pd.read_excel('test_data.xlsx', sheet_name = 'test2')




for index, row in df.iterrows():  
    origin_latin_name = row['origin_organism'].strip().lower()
    other_names_name = row['common_name'].strip().lower()
    tested_species = row['tested_organism'].strip().lower()


if origin_latin_name not in [None, "None", "", "-"]:
    instance = [x[0] for x in Session.query(session,tbs['species'].name).filter_by(name=origin_latin_name).all()]
    if origin_latin_name not in instance:
        origin_species = lib.get_or_create(
            session,
            tbs["species"],
            name = origin_latin_name,
            other_names = other_names_name
        )

    elif origin_latin_name in instance:
        other_names_query = Session.query(session,tbs['species'].other_names).filter_by(name=origin_latin_name)
        other_names_query_list = [x for x in other_names_query]
        original_list2 = list(set([y for y in x[0].split(',') for x in other_names_query_list]))
        if other_names_name not in original_list2:
            original_list2.append(other_names_name)
            new_list = ','.join(original_list2)
            new_names = {'other_names':','.join(original_list2)}

        origin_species = lib.get_or_create(
            session,
            tbs["species"],
            name = origin_latin_name,
            other_names = new_list
        )

Часть из оператора elif не работает.Я столкнулся с двумя проблемами:

(1) Самая последняя ошибка, которую я получил: NameError: имя 'new_list' не определено

(2) еще одна ошибка, которую я получил, это то, что у меня естьеще одна таблица на

map1 = lib.get_or_create(
    session,
    tbs["map1"],
    age_id_id = age,
    name_id_id = origin_species.id
    )

... и там сказано, что origin_species не может быть найден, но я думаю, что это связано с утверждением elif, что каким-то образом объект origin_species не обновляется должным образом.

Если бы кто-нибудь мог помочь, я был бы признателен.

Ответы [ 2 ]

0 голосов
/ 28 сентября 2018

Если вы используете оператор groupby с фреймом данных pandas, вы можете легко это сделать.Код не проверен, дайте мне знать, если есть ошибки

import sys 
from sqlalchemy.orm  import * 
from sqlalchemy  import * 
from dbn.sqlalchemy_module  import lib 
import pd

engine = lib.get_engine(user="user", psw="pwd", db="db", db_host="111.111.111.11")

###Get test data
added_df = pd.read_excel('test_data.xlsx', sheet_name = 'test2')

###Get current database as a pandas object
my_current_df = pd.read_sql_table(
        "table1", engine)

#Now group by origin organism
gb = added_df.groupby('origin_organism')

#For every member that had the same origin organism, return it as a comma seperated list into a new dataframe
df = pd.DataFrame(gb.alias.apply(lambda x: ",".join(x)))

#Now append that dataframe onto the one that came from the database
my_current_df.append(df)

#NOw return that dataframe back to the database
my_current_df.to_sql(
        name='table1',
        con=engine,
        if_exists='replace')
0 голосов
/ 18 сентября 2018

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

alias_list = alias.split(',')

Что также может быть:

alias_list = line[1].split(',')

Вывод:

alias_list:    ['Name1','Name2','Name3']

В настоящее время ваш код выводит:

alias_list = ['Name1,Name2,Name3']

Что, хотя технически это список по типу данных, это бесполезный список того, как вы хотите его использовать.Это потому, что alias_list[0] вернет всю строку, в отличие от 'Name1'

WORD OF WARNING:

Ваш код создает список без необходимости.Вам не нужен список в вашей базе данных, вы можете легко достичь того, что хотите, используя строку, которая оценивается при чтении файла Excel.

Что вам нужно сделать, IMHO, это сохранить строку именкак целая строка, тогда, если вам нужно запросить псевдонимы кого-то, вы можете разбить строку на другой стороне, если это имеет смысл?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...