我制作的程序可以移动文件并将新路径保存在数据库中。 但是,我确实将组合并执行将它们插入数据库的SQL查询存在很大问题。
这是该计划:
#logspc.py
import os
import sqlite3 as lite
import sys
import time
def getspc(path):
dirs = os.listdir(path)
spcfiles = []
for filename in dirs:
(shortname, extension) = os.path.splitext(filename)
if extension == '.spc':
spcfiles.append(filename)
return spcfiles
src=os.path.normpath(r'C:\users\python\nonpython')
dest=os.path.normpath(r'C:\users\python\target')
files=getspc(src)
con = lite.connect('spcbase.db')
cur=con.cursor()
for mfile in files:
oldpath=os.path.normpath(os.path.join(src,mfile))
newpath=os.path.normpath(os.path.join(dest,mfile))
os.rename(oldpath,newpath)
query="INSERT INTO spectra VALUES ('" + newpath + "',SELECT date('now'))"
print query
cur.execute(query)
con.close()
它在线路上崩溃" cur.execute(查询)",呈现此错误:
Traceback (most recent call last):
File "C:/Users/Python/logspc2.py", line 27, in <module>
cur.execute(query)
OperationalError: near "SELECT": syntax error
打印的查询变量的值是
INSERT INTO spectra VALUES ('C:\users\python\target\Bertil.spc',SELECT date('now'))
我从哪里开始?
答案 0 :(得分:3)
获取当前日期的SQLite语法是CURRENT_DATE(CURRENT_TIME和CURRENT_TIMESTAMP也可用):
INSERT INTO spectra VALUES ('C:\users\python\target\Bertil.spc', CURRENT_DATE)
此外,最好不要习惯将SQL语句构建为字符串,而是使用参数化查询:
cur.execute(
'INSERT INTO spectra (PathCol, DateCol) VALUES (?, CURRENT_DATE)',
[newpath]
)
这使您的程序“更安全”,因为没有人可以通过将SQL注入您用于构建字符串的值之一来将SQL隐藏到语句中。虽然这对您的特定程序来说并不是真正的问题*(因为用户不提供newpath
值),但在文件名包含可能会混淆SQLite的字符串解析器的字符的情况下,它也会帮助您。 / p>
最后,另一个好的做法是在INSERT
语句中包含INSERT
值的列的名称。这使得您的代码不那么脆弱 - 没有列名,如果表使用不同的列数或不同的列顺序重新定义,那么您的代码将会中断。通过明确列出列名,您的代码可以在许多常见的表重新定义方案中存活下来。
*
实际上,这是一个有趣的问题 - 在任何文件系统上是否存在通过路径和文件名执行SQL注入的方法?我认为它实际上是可能的!
答案 1 :(得分:0)
遇到同样的问题并找到解决方案:
http://www.experts-exchange.com/questions/28401790/Inserting-dir-filename-to-mysql-from-Python.html
对于我的程序我在Microsoft驱动器中进行递归搜索,fpath是用for循环中的os.path定义的。
print fpath returns -> C:\myfolder\myfile.zip
我认为它会完全按照打印的方式插入INTO。
fpath2 = fpath.replace('\\','\\\\')
SQL = 'INSERT INTO all_zip_files(fpath_zip,status) VALUES("%s", "0");' % (fpath2)
我还发现我需要以特殊方式定义根目录:
PATH = r"c:\" #fails
PATH = r"c:" #works however execute(SQL) fails becaue path becomes c:myfolder\myfile.zip after using fpath.replace('\\',\\\\')
PATH = os.path.normpath("c:/") #WORKS with fpath.replace('\\','\\\\') to create desired windows path for my db
这对我有用,但是这里提出了一个“更好”的解决方案:
Passing a folder location as an SQL parameter in python causes an error