如何使用fast_executemany将mm / dd / yyyy字符串插入SQL Server日期时间列?

How to insert mm/dd/yyyy strings into a SQL Server datetime column using fast_executemany?

提问人:mkylfnur 提问时间:6/4/2023 最后编辑:Gord Thompsonmkylfnur 更新时间:6/5/2023 访问量:113

问:

我正在从 BQ 查询数据。我必须将其插入到 SQL Server 2008 中。

伪代码:

# get results from bigquery

client = bigquery.Client()
result = client.query(sql).result()

# create parametrized insert sql statement

sql = 'INSERT INTO [SANDBOX].[dbo].[table_stg] VALUES ((?),(?),(?),(?),(?),(?),(?),(?),(?),(?))'

data = [(2016, 'STRING', 'STRING', 'STRING', 'STRING', 'STRING', INT, 'STRING', '09/28/2015', '09/25/2016'), 
(2016, 'STRING', 'STRING', 'STRING', 'STRING', 'STRING', INT, 'STRING', '09/28/2015', '09/25/2016')]

# target table schema

[varchar](50) NULL,
[varchar](50) NULL,
[varchar](50) NULL,
[varchar](50) NULL,
[varchar](50) NULL,
[varchar](50) NOT NULL,
[int] NULL,
[varchar](50) NULL,
[datetime] NULL,
[datetime] NULL


# insert into sql server with fast_executemany

cursor.fast_executemany = True
cursor.executemany(sql, data)
conn.commit()
cursor.close()
conn.close()

因此,当我运行cursor.fast_executemany = True的cursor.executemany(sql, data)时,我收到错误:

强制转换规范的字符值无效。

字符串数据,右截断:长度 44 缓冲区 20,HY000

该代码在没有 cursor.fast_executemany = True 的情况下完美运行,但它以单次提交执行每次插入,这意味着 8 小时才能传输 2 百万行。

提前感谢您的帮助。 此外,如果有一些过滤机制,我可以起诉拆分为fast_execute和正常执行,我将不胜感激。

编辑:根据评论编辑问题

sql-server sql-server-2008-r2 pyodbc

评论

0赞 Thom A 6/4/2023
为什么要同时标记 SQL Server 和 BigQuery?它们是完全不同的产品。
0赞 mkylfnur 6/4/2023
因为我通过 >client = bigquery 从 BigQuery 获取结果。Client() >result = client.query(query).result() 也许这对解决我的问题有效。
0赞 Gord Thompson 6/4/2023
可能相关:stackoverflow.com/q/61204788/2144390
0赞 mkylfnur 6/5/2023
谢谢,这是一本好书,我已经解决了空列和日期时间的问题。我唯一的问题(我认为)是字符串周围有双引号,里面有单引号,就像某种 bq apoi - python - tsql 2008 conclict。或者也许是其他/更多的东西。
0赞 Gord Thompson 6/5/2023
对于格式正确的参数化 INSERT 查询(例如,.请考虑添加一个可以重现问题的最小可重现示例crsr.executemany("INSERT INTO my_table (my_column) VALUES (?)", [("my'problem",), ("what'ever",)])

答:

0赞 Gord Thompson 6/5/2023 #1

此处的相关问题说明了如何影响对列的空字符串参数的解释方式。使用 ,空字符串被解释为 。使用 时,空字符串参数会导致“强制转换规范的字符值无效”错误。fast_executemany = Truedatetimefast_executemany = False1900-01-01 00:00:00fast_executemany = True

字符串参数似乎也是如此。该格式可能不明确(是 OR ?),并且 SQL Server 在 UNDER 下做出假设,而不是在 下做出假设。aa/bb/yyyymm/dd/yyyydd/mm/yyyyfast_executemany = Falsefast_executemany = True

对于定义为d1 [datetime]

cursor.fast_executemany = False
cursor.executemany(
    "INSERT INTO [SANDBOX].[dbo].[table_stg] (d1) VALUES (?)",
    [("09/28/2015",)]
)

但这失败了

cursor.fast_executemany = True
cursor.executemany(
    "INSERT INTO [SANDBOX].[dbo].[table_stg] (d1) VALUES (?)",
    [("09/28/2015",)]
)

但是,这有效:

cursor.fast_executemany = True
cursor.executemany(
    "INSERT INTO [SANDBOX].[dbo].[table_stg] (d1) VALUES (?)",
    [("2015/09/28",)]
)

因此,要么重新格式化字符串,要么将它们解析为对象yyyy/mm/dddatetime

cursor.fast_executemany = True
cursor.executemany(
    "INSERT INTO [SANDBOX].[dbo].[table_stg] (d1) VALUES (?)",
    [(datetime.datetime.strptime("09/28/2015", "%m/%d/%Y"),)]
)

评论

0赞 mkylfnur 6/6/2023
感谢 Gord 的详细回答。我现在正在测试它。您能向我推荐一些阅读材料,以便我可以创建一个符合fast_executemany的数据验证器吗?