【问题标题】:Insert record from list if not exists in table如果表中不存在,则从列表中插入记录
【发布时间】:2019-12-19 22:21:08
【问题描述】:
cHandler = myDB.cursor()
cHandler.execute('select UserId,C1,LogDate from DeviceLogs_12_2019') // data from remote sql server database

curs = connection.cursor() 
curs.execute("""select * from biometric""")  //data from my database table

lst = []
result= cHandler.fetchall()
for row in result:
    lst.append(row)

lst2 = []
result2= curs.fetchall()
for row in result2:
    lst2.append(row)

t = []
r = [elem for elem in lst if not elem in lst2]
for i in r: 
    print(i)
    t.append(i)

for i in t:
    frappe.db.sql("""Insert into biometric(UserId,C1,LogDate) select '%s','%s','%s'  where not exists(select * from biometric where UserID='%s' and LogDate='%s')""",(i[0],i[1],i[2],i[0],i[2]),as_dict=1)

如果记录不存在但出现错误,我正在尝试上面的代码将数据插入到我的表中:

pymysql.err.ProgrammingError: (1064, "您的 SQL 语法有错误;请查看与您的 MariaDB 服务器版本相对应的手册,了解在 '1111''、''in'' 附近使用的正确语法, ''2019-12-03 06:37:15'' 其中不存在(从第 1 行的生物特征中选择 *")

我做错了什么或有任何其他方法可以实现这一目标吗?

【问题讨论】:

标签: python mysql database erpnext


【解决方案1】:

看来您可能有四个问题:

  1. selectwhere not exists 之间缺少一个 from 子句。
  2. 使用准备好的语句时,不要将占位符参数%s 括在引号内。您的 SQL 应该是:
  3. 你的循环:

循环:

t = []
r = [elem for elem in lst if not elem in lst2]
for i in r: 
    print(i)
    t.append(i)

如果您尝试仅包含来自远程站点的不会重复的行,那么您应该明确检查两个重要的字段,即UserIdLogDate。但是,既然您的 SQL 负责确保您排除这些重复的行,那么这有什么意义呢?另外,将r 中的所有内容复制到t 有什么意义?

SQL:

Insert into biometric(UserId,C1,LogDate) select %s,%s,%s from DUAL where not exists(select * from biometric where UserID=%s and LogDate=%s

但即使使用上述 SQL 也存在问题

如果not exists 子句为假,则select %s,%s,%s from DUAL ... 不返回任何列,并且列数将与您尝试插入的列数(即三)不匹配。

如果您担心由于 (UserId, LogDate) 是 UNIQUE 或 PRIMARY KEY 而由于重复键而导致错误,则在 INSERT 语句中添加 IGNORE 关键字,然后如果具有该键的行已经存在,则插入将是忽略。但是由于您没有提供此信息,因此无法知道:

for i in t:
    frappe.db.sql("Insert IGNORE into biometric(UserId,C1,LogDate) values(%s,%s,%s)",(i[0],i[1],i[2]))

如果您不希望多行具有相同的(UserId, LogDate) 组合,那么您应该在这两列上定义一个 UNIQUE KEY,然后上面的 SQL 就足够了。还有一个 INSERT 语句的ON DUPLICATE KEY SET ... 变体,如果密钥存在,您可以进行更新(查看此内容)。

如果您没有在这两列上定义 UNIQUE KEY,或者您需要打印出正在更新的那些行,那么您确实需要测试是否存在现有键。但这将是这样做的方法:

cHandler = myDB.cursor()
cHandler.execute('select UserId,C1,LogDate from DeviceLogs_12_2019') // data from remote sql server database
rows = cHandler.fetchall()
curs = connection.cursor() 
for row in rows:
    curs.execute("select UserId from biometric where UserId=%s and LogDate=%s", (ros[0], row[2])) # row already in biometric table?
    biometric_row = curs.fetchone()
    if biometric_row is None: # no, it is not
        print(row)
        frappe.db.sql("Insert into biometric(UserId,C1,LogDate) values(%s, %s, %s)", (row[0],row[1],row[2]))

【讨论】:

  • 我认为还有第三个问题:逻辑前提有缺陷。
  • 但我是从列表而不是表格中插入数据。
  • @Strawberry 你能解释一下吗?
  • 如果您从列表中选择,则该表命名为DUAL
猜你喜欢
  • 2014-03-08
  • 1970-01-01
  • 2021-09-03
  • 2018-12-26
  • 1970-01-01
  • 1970-01-01
  • 2011-03-11
相关资源
最近更新 更多