如何使用sqlalchemy将数据加载到现有数据库表中?

时间:2015-07-19 13:56:48

标签: python mysql dictionary sqlalchemy

我从excel文件加载数据并组织为python dict,其中每个键都是数据库表名,其值被定义为词典列表(行)

system_data = {table_name1:[{'col_1':val1, 'col2': val1...},
                            {'col_1':val2, 'col2': val2..}..],     
               table_name2:[{},{}..],[{},{}..]..}

table_names选择system_data个键和值时,需要将此数据加载到现有数据库中。

此外,我使用了order_table列表,我已按特定顺序创建该列表,以避免在加载数据时出现FK问题。

以下是代码(我尝试过的1000个版本中的一个):

from sqlalchemy import create_engine
from sqlalchemy.sql import insert

def alchemy_load():
    system_data = load_current_system_data()
    engine = create_engine('mysql+pymysql://username:password@localhost/my_db')
    conn = engine.connect()
    for table_name in ordered_tables:
        conn.execute(insert(table_name, system_data[table_name]))
    print("System's Data successfully loaded into Database!")

此函数会产生以下错误:

"TypeError: 'method' object is not iterable"

我几乎整天都浪费在这些东西上((

所有在线示例都描述了当用户使用MetaData并创建自己的表时的情况......没有任何关于如何将数据实际添加到现有表中的信息。

使用"数据集"解决了我的问题。库。

代码:

import dataset

def current_data():
    db = dataset.connect(url='mysql+pymysql://user:pass@localhost/my_db')
    system_data = load_current_system_data()

    for table_name in ordered_tables:
        db[table_name].insert_many(system_data[table_name])
    print("System's Data successfully loaded into Database!")

但是,我不知道如何使用sqlalchemy实现此代码...

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:4)

使用SQLAlchemy metadata的一种可能解决方案如下:

In [7]:

from sqlalchemy.schema import MetaData
meta = MetaData()
meta.reflect(bind=engine)

In [20]:

for t in meta.tables:
    for x in engine.execute(meta.tables[t].select()):
        print x
(1, u'one')
(2, u'two')
(1, 1, 1)
(2, 1, 2)
(3, 2, 0)
(4, 2, 4)

(我使用select而不是insert并将其应用到我试用过的愚蠢的数据库中。)

希望它有所帮助。

编辑:在评论之后,我添加了一些说明。

MetaData()中,tables是架构中表格的字典。字典按表名称进行,它实际上与代码中的字典非常相似。您可以像这样迭代元数据,

for table_name, table in meta.tables.items():
    for x in engine.execute(table.select()):
        print x

或者,尝试将其调整到您的代码中,您可以执行类似的操作,

for table_name in ordered_tables:
    conn.execute(meta.tables[table_name].insert_many(system_data[table_name]))

答案 1 :(得分:0)

所以这是最终的代码(非常感谢Irnzcig的指导,以及我自己彻底重新阅读官方SA文档^ _ ^)。

from sqlalchemy import create_engine, MetaData
# from myplace import load_current_system_data() and other relevant functions

def alchemy_current():
    system_data = load_current_system_data()
    engine = create_engine('mysql+pymysql://user:password@localhost/your_db_name')
    meta = MetaData()
    meta.reflect(bind=engine)
    conn = engine.connect()
    for table_name in ordered_tables:
        conn.execute(meta.tables[table_name].insert().values(system_data[table_name]))
    conn.close()
    # engine.dispose()

    print("System's Data successfully loaded into Database!")

所有这一切都应该有效,假设有人:

    1. Existing mysql database.
    2. An organized data as I've described prior in this question. 
    3. An ordered `table_name_list` in order to keep referential integrity and avoid FK problems.

如果有人有“改进建议”,我会很高兴听到。

伊凡。