【问题标题】:PYODBC Inserting data into datetime column produces incorrectly formatted tablePYODBC 将数据插入日期时间列会产生格式不正确的表
【发布时间】:2019-10-07 10:53:53
【问题描述】:

我目前正在编写一个程序,该程序将从 Excel 电子表格中获取数据并将其插入到我在程序中创建的 sql server 表中。

我之前已将 datetime 列指定为 nvarchar(250) 以使整个程序正常工作,但是当我将其更改为 datetime 时,数据输入到了错误的列中?其余代码也适用于 nvarchar 数据类型。

import pyodbc

connection_string = r'connection_string'
data = 'file_path'

conn = pyodbc.connect(connection_string)
cur = conn.cursor()

createtable = """
create table table1(
    ID Int NULL,
    Date datetime(250) NULL,
    City nvarchar(250) NULL,
    Country nvarchar(250) NULL,
    Image nvarchar(250) NULL,
    Length nvarchar(250) NULL,
    Date_Of_capture nvarchar(250) NULL,
    Comments nvarchar(1000) NULL
    )"""

truncatetable = """truncate table table1"""

with open(data) as file:
    file.readline()
    lines = file.readlines()

if cur.tables(table="table1").fetchone():
    cur.execute(truncatetable)
    for line in lines:
        cols = line.split(',')
        cols = line.replace("'", "")
        sql = "INSERT INTO table1 VALUES({}, '{}', '{}', '{}', '{}', '{}','{}','{}')".format(cols[0], cols[1],cols[2], cols[3], cols[4], cols[5], cols[6], cols[7])
        cur.execute(sql)
else:
    cur.execute(createtable)
    for line in lines:
        cols = line.split(',')
        sql = "INSERT INTO table1 VALUES({}, '{}', '{}', '{}', '{}', '{}','{}','{}')".format(cols[0], cols[1],cols[2], cols[3], cols[4], cols[5], cols[6], cols[7])
        cur.execute(sql)

conn.commit()

conn.close()

我希望日期列显示为日期时间数据类型,同时包含在一个列中,但是它会更改表格,以便所有列都不正确并且日期的每个数字都在不同的列中?

非常感谢任何帮助。谢谢。

【问题讨论】:

  • 请从输入和输出中添加一些数据。
  • 我必须假设您的create table 语句没有被执行,因为datetime(250) 肯定会抛出异常。另外,请阅读参数化查询edit你的问题,向我们展示lines的样子。
  • 抱歉,我不知道如何显示数据样本?有什么建议吗?
  • 您不能open 处理二进制格式类型(.xls、.xlsx、.xlsm、.xlsb)的 Excel 文件。很可能,您的数据是 txt 或 csv,它们都不是 Excel 文件。
  • @Parfait - 如果安装了 Office,Windows 会将 .csv 与 Excel 相关联,因此在这种情况下,人们认为 .csv 是“Excel 文件”是可以原谅的。 (“好吧,我双击该文件,它会在 Excel 中打开……”)

标签: python sql sql-server pyodbc


【解决方案1】:

考虑以下最佳做法:

  • 始终在INSERT INTO 甚至SELECT 子句中指定列,特别是使用INSERT INTO myTable (Col1, Col2, Col3, ...),这有助于提高可读性和可维护性;

  • 将参数化与准备好的语句一起使用,以避免在其他重要项目中出现引号转义或类型转换。此外,Python 允许将元组传递给 cursor.execute()params 参数,而无需列出每个单独的列。

  • 使用 Python 的 csv 库遍历带有列表或字典的 CSV 文件以进行正确对齐并避免内存密集型 .readlines() 调用;

  • CREATE TABLETRUNCATE 组合在一个SQL 调用中,以避免if 条件语句与游标提取调用。

查看调整后的代码。

import csv
...

action_query = """
    IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'mytable')
      BEGIN
        TRUNCATE TABLE table1
      END
    ELSE
      BEGIN
        CREATE TABLE table1(
           ID Int NULL,
           Date datetime NULL,
           City nvarchar(250) NULL,
           Country nvarchar(250) NULL,
           Image nvarchar(250) NULL,
           Length nvarchar(250) NULL,
           Date_Of_capture nvarchar(250) NULL,
           Comments nvarchar(1000) NULL
        )
      END
""")

cur.execute(action_query)
conn.commit()

# PREPARED STATEMENT
append_query = """INSERT INTO mytable (ID, Date, City, Country, Image, 
                                       Length, Date_Of_capture, Comments)
                  VALUES (?, ?, ?, ?, ?, ?, ?, ?)
               """

# ITERATE THROUGH CSV AND INSERT ROWS
with open(mydatafile) as f:
    next(f) # SKIP HEADERS
    reader = csv.reader(f)

    for r in reader:
        # RUN APPEND AND BIND PARAMS
        cur.execute(append_query, params=r)
        conn.commit()

cur.close()
conn.close()

【讨论】:

  • 非常感谢!不幸的是,当我正在学习课程时,我需要检查该表是否存在于 python 中,但是我能够采取一些措施来完成它!感谢您的回复!
  • 很高兴听到并乐于提供帮助!希望您的学习课程强调参数化。
猜你喜欢
  • 2021-09-30
  • 1970-01-01
  • 2014-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多