Python 如何在此代码上实现session.add:

Python 如何在此代码上实现session.add:,python,sqlalchemy,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

所以,我需要一些帮助来加快这个脚本的运行速度,下面是我的脚本

#!/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)
但这只适用于一个列表,我有14个列表

有人知道如何实现session.add而不是execute吗


谢谢大家!

首先,我要创建一个类,例如CDRItem,如下所示:

class CDRItem(db.Session):
    def __init__(served_imsi ....):
        served_imsi = self.served_imsi
等等。 然后我将遍历cdr的行,创建新的CDRItem类对象并将它们放入列表中。
创建列表后,剩下的就是

session.add_all(created_list)

首先,我要创建一个类,例如CDRItem,如下所示:

class CDRItem(db.Session):
    def __init__(served_imsi ....):
        served_imsi = self.served_imsi
等等。 然后我将遍历cdr的行,创建新的CDRItem类对象并将它们放入列表中。
创建列表后,剩下的就是

session.add_all(created_list)
有两种(主要)方法可以使用SQLAlchemy。您目前的做法是使用API。使用
session.Add
是API的一部分。它们有两个不同的用途,我建议阅读一些文档,了解其中的差异

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

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

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

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

i.execute(...)
……你应该

db.execute(i, ...)
性能问题是您遇到的问题涉及对每行使用
execute
一次。因此,每个插入都在自己的事务中运行,这可能会很慢。你可以做一些像

all_data = []

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

    count += 1
我建议您在进行此操作时启用
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)
#/usr/bin/env python
导入全局、操作系统、csv
从sqlalchemy导入*
db=创建引擎('sqlite:///CDR.db,echo=False)
元数据=元数据(db)
CDRS=Table('CDRS',元数据,自动加载=True)
insert_语句=CDRS.insert()
所有_数据=[]
路径='/home/cneps/cdr/*.cdr'
对于glob.glob(路径)中的文件:
#使用“with”在完成“f”时自动关闭它。
打开(文件)为f时:
对于f中的行:
d={
“已送达”:行[17:17+16],
....
}
所有_数据。追加(d)
#不需要那个“whilecount
使用SQLAlchemy有两种(主要)方法。您目前的做法是使用API。使用
session.Add
是API的一部分。它们有两个不同的用途,我建议阅读一些文档,了解其中的差异

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

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

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

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

i.execute(...)
……你应该

db.execute(i, ...)
性能问题是您遇到的问题涉及对每行使用
execute
一次。因此,每个插入都在自己的事务中运行,这可能会很慢。你可以做一些像

all_data = []

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

    count += 1
我建议您在进行此操作时启用
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)
#/usr/bin/env python
导入全局、操作系统、csv
从sqlalchemy导入*
db=创建引擎('sqlite:///CDR.db,echo=False)
元数据=元数据(db)
CDRS=Table('CDRS',元数据,自动加载=True)
insert_语句=CDRS.insert()
所有_数据=[]
路径='/home/cneps/cdr/*.cdr'
对于glob.glob(路径)中的文件:
#使用“with”在完成“f”时自动关闭它。
打开(文件)为f时:
对于f中的行:
d={
“已送达”:行[17:17+16],
....
}
所有_数据。追加(d)
#不需要那个“whilecount
谢谢!我会调查的!什么是<