如何在这段代码上实现session.add:

时间:2013-11-29 19:03:15

标签: python sqlalchemy

所以,我需要一些帮助才能使这个脚本运行得更快,下面是我的脚本。

#!/usr/bin/env python
import glob,os, csv
from sqlalchemy import *

count = 0
served_imsi = []
served_imei = []
served_msisdn = []
sgsn_address = []
ggsn_address = []
charging_id = []
apn_network = []
location_area_code = []
routing_area = []
cell_identity = []
service_area_code = []
s_charging_characteristics = []
plmn_id = []

path = '/home/cneps/cdr/*.cdr'
for file in glob.glob(path):
    f = open(file)
    for lines in f:
        served_imsi.append(lines[17:17+16])
        served_imei.append(lines[47:47+16])
        served_msisdn.append(lines[65:65+18])
        sgsn_address.append(lines[83:83+32])
        ggsn_address.append(lines[115:115+32])
        charging_id.append(lines[147:147+10])
        apn_network.append(lines[157:157+63])
        location_area_code.append(lines[296:296+4])
        routing_area.append(lines[300:300+2])
        cell_identity.append(lines[302:302+4])
        service_area_code.append(lines[306:306+4])
        s_charging_characteristics.append(lines[325:325+2])
        plmn_id.append(lines[327:327+6])

db = create_engine('sqlite:///CDR.db',echo=False)
metadata = MetaData(db)
CDRS = Table('CDRS', metadata, autoload=True)
i = CDRS.insert()

while count < len(served_imei):

        i.execute(Served_IMSI=served_imsi[count],
        Served_IMEI=served_imei[count],
        Served_MSISDN=served_msisdn[count],
        SGSN_Address=sgsn_address[count],
        GGSN_Address=ggsn_address[count],
        Charging_ID=charging_id[count],
        APN_Network=apn_network[count],
        LAC=location_area_code[count],
        RAC=routing_area[count],
        Cell_Identity=cell_identity[count],
        Service_Area_Code=service_area_code[count],
        S_Charging_Characteristics=s_charging_characteristics[count],
        PLMN_ID=plmn_id[count])
        count += 1

for files in glob.glob(path):
        os.remove(files)

代码很好。但是我花了太长时间,我问了一位朋友,他建议使用session.add来加快速度。

我带来的解决方案是这样的:

for item in lists:
    session.add(item)

但这只适用于一个列表,我有14个列表。

有没有人知道如何将session.add实现到我的代码中,而不是执行?

谢谢!

2 个答案:

答案 0 :(得分:1)

有两种(主要)方法可以使用SQLAlchemy。您目前正在使用SQLAlchemy Expression Language API的方式。使用session.AddObject Relational API的一部分。它们有两个不同的用途,我建议阅读一些文档来了解差异。

对象关系API(通常称为ORM或“对象关系映射器”)使用下面的SQLAlchemy表达式语言,因此您可以在SQLAlchemy Expression API中执行ORM API中的任何操作(虽然语法不同)。所以,我建议除非你真的需要,否则不要试图将代码转换到其他API。

作为完全重写代码的替代方法,请注意您这样做:

CDRS = Table('CDRS', metadata, autoload=True)
i = CDRS.insert()

i成为insert expression。您可以使用它来动态创建插入语句。您可以通过打印i来尝试这一点:它看起来像带有参数的SQL字符串(但请注意,该值实际上不是字符串;它是一个帮助自动创建SQL字符串的对象)。将该插入对象传递给execute方法(以及所有参数)时,生成的SQL字符串将被执行。

现在,您正在使用insert语句的execute方法。首选方法是在引擎上使用execute方法。所以,而不是......

i.execute(...)

......你应该......

db.execute(i, ...)

性能问题是您遇到涉及每行使用execute一次的问题。因此,每个INSERT都在自己的事务中运行,这可能很慢。你可以做点像......

all_data = []

while count < len(served_imei):
    data = {
        'Served_IMSI' : served_imsi[count],
        'Served_IMEI' : served_imei[count],
        ...
    }
    all_data.append(data)

    count += 1

现在,all_data包含一个字典列表,每个字典包含insert语句的键(列名)和值(列值)。然后,你可以使用......

db.execute(i, all_data)

我建议您在开展此工作时启用echo以了解SQLAlchemy正在做什么:

db = create_engine('sqlite:///CDR.db',echo=True) # Change `echo` from False to True

你的下一步是删除你的两个循环,并创建我刚刚从代码中从文件中读取的部分显示的字典。例如:

#!/usr/bin/env python
import glob,os, csv
from sqlalchemy import *

db = create_engine('sqlite:///CDR.db',echo=False)
metadata = MetaData(db)
CDRS = Table('CDRS', metadata, autoload=True)
insert_statement = CDRS.insert()

all_data = []

path = '/home/cneps/cdr/*.cdr'
for file in glob.glob(path):
    # Use "with" to automatically close "f" when we're done with it.
    with open(file) as f:
        for lines in f:
            d = {
                'Served_IMSI' : lines[17:17+16],
                ....
            }
            all_data.append(d)

# No need for that "while count < len(served_imei)" loop, we can now just do...
db.execute(insert_statement, all_data)

答案 1 :(得分:0)

我会创建一个类,例如。 CDRItem喜欢:

class CDRItem(db.Session):
    def __init__(served_imsi ....):
        served_imsi = self.served_imsi

等等。 然后我将遍历cdr的行,创建新的CDRItem类对象并将它们放入列表中 列表创建后,剩下的就是

session.add_all(created_list)
相关问题