在SQLAlchemy数据库选项卡中创建并附加到列表

2024-09-28 23:23:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我在学习炼金术,我被卡住了。 我有一个SQL表(table1)有两个字段:“name”和“othernames”

我有一个包含两列的excel文件:

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

我想把excel文件读入table1,这样它看起来是这样的(即同一行的所有别名都在一行上):

^{pr2}$

这就是我想做的。我尝试的代码(带注释):

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 db表中的字段条目添加到列表中。在

更新1:我已经根据下面的建议更新了我的代码。但是我仍然有这个问题。这是完整的目标、代码和测试文件: 目标:

我在数据库中有一个表(关于进入表的测试文件,见下文)。表有两个字段,name(拉丁名,如homo sapiens)和其他名称(常用名称,如human,man)。我想更新表中的字段(其他名称),因此不需要:

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

我有:

Rana rugosa human,man,frog,cow

测试数据文件如下所示:

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)我最近得到的错误: 名称错误:未定义名称“new_list”

(2)我得到的另一个错误是我有另一张桌子在前面

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

…它说找不到起源物种,但我认为这与elif的声明有关,不知何故原始物种对象没有得到正确更新。在

如果有人能帮忙,我会很感激的。在


Tags: thenameinfornamessessionlibalias
2条回答

如果在pandas数据帧中使用groupby语句,则可以很容易地做到这一点。代码未经测试如果有错误请告诉我

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')

简单的错误。你没有给它一个单子。我不知道为什么它们会出现在不同的行中,但是,我会更改以下内容,因为目前我看不到将名称拆分为列表的位置,我看到的只是使用append将字符串分配到列表中。在

alias_list = alias.split(',')

也可以是:

^{pr2}$

输出:

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

当前代码输出:

alias_list = ['Name1,Name2,Name3']

虽然从技术上讲,它是一个按数据类型划分的列表,但对于您想要使用它的方式来说,它是一个毫无价值的列表。这是因为alias_list[0]将返回整个字符串,而不是{}

警告语:

您的代码正在创建不必要的列表。数据库中不需要列表,通过使用读取excel文件时计算的字符串,可以轻松地实现您想要的结果。在

IMHO应该做的是将名称字符串存储为一个完整的字符串,然后如果您需要查询某人的别名,那么您可以将字符串拆分到另一端,如果这有意义的话?在

相关问题 更多 >