SQLAlchemy插入执行功能

时间:2019-06-23 18:20:50

标签: python mysql sqlalchemy

我正在尝试通过SQLAlchemy将字典列表批量插入MySQL数据库。在列表中,每个字典都有时间和温度。时间值是ISO时间字符串。我试图让MySQL在创建日期时间对象以存储到数据库的途中使用STR_TO_DATE函数。

我已经通过insert()。values({'time':func.STR_TO_DATE(row.time,date_str),'temp'= row.temp})成功完成了工作

示例代码:

def func():
    rgb_image=cv2.imread('filename')
    gray_image=cv2.imread('filename',0)

    rgb_converted_to_gray_image=np.dot(rgb_image[...,:3], [0.114, 0.587, 0.299])

    print("Before multiplying with 255")
    print(gray_image)
    print("------------")
    print(rgb_converted_to_gray_image)

    gray_image=gray_image*255.0
    rgb_converted_to_gray_image=rgb_converted_to_gray_image*255

    print("After multiplying with 255")
    print(gray_image)
    print("------------")
    print(rgb_converted_to_gray_image)

不确定如何通过将参数绑定到可以调用STR_TO_DATE的单个输入值来使此工作正常进行,以便可以通过字典列表插入数据。

第二次修改:

这是我有效的蛮力代码。试图找到一种使用SQLALchemy Core来完成此语句的方法。

import sqlalchemy
from sqlalchemy import create_engine, MetaData, Table, Column, func
from sqlalchemy.dialects.mysql import DATETIME, INTEGER, insert

temp_data = [{'time':'2019-02-07T14:01:00.000000000Z', 'temperature':68},
             {'time':'2019-02-07T14:02:00.000000000Z', 'temperature':69},
             {'time':'2019-02-07T14:03:00.000000000Z', 'temperature':70},
             {'time':'2019-02-07T14:04:00.000000000Z', 'temperature':71}]


date_string = '%Y-%m-%dT%H:%i:%S.%f000Z'
mysql_metadata = MetaData()
mysql_table = Table('temperature', mysql_metadata,
                    Column('time', DATETIME(fsp = 6), primary_key = True),
                    Column('temperature', INTEGER()))

def single_insert():
    engine = create_engine('mysql://test_user:test@localhost/temperature',
                                  echo = False)
    mysql_table.drop(engine, checkfirst = True)
    mysql_table.create(engine)
    conn = engine.connect()
    for row in temp_data:
        conn.execute(mysql_table.insert().values(time = func.STR_TO_DATE(row['time'], date_string),
                                                 temperature = row['temperature']))



def insert_many():
    engine = create_engine('mysql://test_user:test@localhost/temperature',
                                  echo = False)    
    mysql_table.drop(engine, checkfirst = True)
    mysql_table.create(engine)
    conn = engine.connect()
    conn.execute(mysql_table.insert(), temp_data)

第三次修改:

最终想要针对Python Datetime strptime与MySQL方法进行比较。希望看看哪个更快。

2 个答案:

答案 0 :(得分:0)

对字典列表进行批量插入的一种方法是对每个键使用bindparam并执行execute

from sqlalchemy.sql.expression import bindparam

temp_data = [{'time':'2019-02-07T14:01:00.000000000Z', 'temperature':68},
         {'time':'2019-02-07T14:02:00.000000000Z', 'temperature':69},
         {'time':'2019-02-07T14:03:00.000000000Z', 'temperature':70},
         {'time':'2019-02-07T14:04:00.000000000Z', 'temperature':71}]

def insert_many():

    engine = create_engine('mysql://test_user:test@localhost/temperature',
                              echo = False)    
    mysql_table.drop(engine, checkfirst = True)
    mysql_table.create(engine)
    conn = engine.connect()

    statement = Mysql_table.insert().values({
            'time' : bindparam('time'),
            'temperature' : bindparam('temperature')
            })
    conn.execute(statement, temp_data)
    conn.close()

关于STR_TO_DATE函数,如何在字典本身中更新这些值,然后执行insert_many()函数

for item in temp_data:
    item.update((k, func.STR_TO_DATE(v)) for k,v in item.items() if k == 'time')

您始终可以使用时间模块来衡量时间执行

import time
from datetime import datetime
start_time = time.time()
func.STR_TO_DATE('date_value') # datetime.strptime(date_string, "%d %B, %Y")
print('--%s seconds --' %(time.time() - start_time)

答案 1 :(得分:0)

SQLAlchemy(SA)doc在页面底部具有此示例,该示例说明了在SA Core引擎上使用DBAPI的API executemany 。我认为代码示例无效(如果引擎的方言使用位置插入,则只需要 args 中的原始值,而无需字段名称),但是它显示了必要的调用。请记住, executemany 接受SQL语句字符串,因此 bindparams 部分仅用于辅助构建字符串-您可能会发现将语句写为文本会更简单。然后将 bindparams 部分砍下。但是,您可以首先尝试 bindparams 来查看SA如何为范围内的数据类型生成语句。

此方法的优点是,如果您使用流行的后端(如MySQL),则在DBAPI中可以对真正的 executemany 进行优化。

在比示例中使用的语法更现代的语法中,应通过调用 engine.raw_connection()

来打开SA连接。