I need python to issue a query via pyodbc to insert a .PNG file into a table as a blob. The problem seems to have something to do with how the path to the file is represented. Here's some code:
OutFilePath = 'd:\\DilerBW_images\\'
OutFileName = SubjID+'_'+str(UserID)+'_'+DateTime+'.png'
print OutFilePath+OutFileName
qstring = ('insert into [wpic-smir].[Diler_BW].[Beckwith].[PlotImages](ID, UserID, ImageType, MoodType, ImageIndex, ImageData)'
'select '+str(SubjID)+' as ID, '+str(UserID)+' as UserID,'
'1 as ImageType,'
'NULL as MoodType,'
'NULL as ImageIndex,'
'* from OPENROWSET(Bulk \''+OutFilePath+OutFileName+'\', SINGLE_BLOB) as ImageData')
print qstring
cursor.execute(qstring)
conn.commit()
`
And here's the output:
d:\DilerBW_images\999123_999123_2015-01-20_14-25-07.013000.png
insert into [wpic-smir].[Diler_BW].[Beckwith].[PlotImages](ID, UserID, ImageType, MoodType, ImageIndex, ImageData)select 999123 as ID, 999123 as UserID,1 as ImageType,NULL as MoodType,NULL as ImageIndex,* from OPENROWSET(Bulk 'd:\DilerBW_images\999123_999123_2015-01-20_14-25-07.013000.png', SINGLE_BLOB) as ImageData
Now, here's the error I get:
Traceback (most recent call last):
File "c:\pythonscripts\DilerBW_Plot_Single_report_2_EH.py", line 253, in <module>
cursor.execute(qstring)
pyodbc.ProgrammingError: ('42000', '[42000] [Microsoft][SQL Server Native Client 11.0][SQL Server]Cannot bulk load because the file "d:\\DilerBW_images\\999123_999123_2015-01-20_14-25-07.013000.png" could not be opened. Operating system error code 3(The system cannot find the path specified.). (4861) (SQLExecDirectW)')
Sorry this is so long. Notice that the file path in the error message includes double backslashes, where the query only includes singles. I have looked extensively at the various methods to build the string (os.path.sep, using a raw string, os.path.join), but it doesn't seem to matter, and I'm not certain the input string is the problem. Again, if I cut and paste the query as it's presented in the output into SSMS and execute it, it works fine.
Thanx.
Related
I'm trying to get an admin account to edit a 'rank' (basically access level) for one of the profiles in my data-base. The error is:
Traceback (most recent call last):
File "U:/A-level Computor Science/Y12-13/SQL/sqlite/Databases/ork task/Python for SQL V_2.py", line 154, in <module>
main()
File "U:/A-level Computor Science/Y12-13/SQL/sqlite/Databases/ork task/Python for SQL V_2.py", line 9, in main
start_menu()
File "U:/A-level Computor Science/Y12-13/SQL/sqlite/Databases/ork task/Python for SQL V_2.py", line 22, in start_menu
login()
File "U:/A-level Computor Science/Y12-13/SQL/sqlite/Databases/ork task/Python for SQL V_2.py", line 72, in login
Mek_menu()
File "U:/A-level Computor Science/Y12-13/SQL/sqlite/Databases/ork task/Python for SQL V_2.py", line 108, in Mek_menu
where Uzaname = %s""" % (NewRank, Findaname))
sqlite3.OperationalError: unrecognized token: "0rk_D4T4B453"`
The code that seems to be the problem is:
cursor.execute(""" update 0rk_D4T4B453.Da_Boyz
set Rank = %s
where Uzaname = %s""" % (NewRank, Findaname))
Originally, it was all on one line and it didn't work, and now I've tried it on multiple lines and it still doesn't work. So I checked here to see if anyone could help.
EDIT1: Thanks for the suggestions. None of them have fixed the code, but I've narrowed the problem code to: where Uzaname = %s""" % (NewRank, Findaname))
Unless you use ATTACH, SQLite (a file-level database) does not recognize other databases. Usually server-level databases (Oracle, Postgres, SQL Server, etc.) use the database.schema.table reference. However, in SQLite the very database file you connect to is the main database in scope. But ATTACH allows you to connect to other SQLite databases and then recognizes database.table referencing.
Additionally, for best practices:
In sqlite3 and any other Python DB-APIs, use parameterization for literal values and do not format values to SQL statement.
In general Python, stop using the de-emphasized (not deprecated yet) string modulo operator, %. Use str.format or more recent F-string for string formatting. But neither is needed here.
Altogether, if you connect to the 0rk_D4T4B453 database, simply query without database reference:
conn = sqlite3.connect('/path/to/0rk_D4T4B453.db')
cursor = conn.cursor()
# PREPARED STATEMENT WITH QMARK PLACEHOLDERS
sql = """UPDATE Da_Boyz
SET Rank = ?
WHERE Uzaname = ?"""
# BIND WITH TUPLE OF PARAMS IN SECOND ARG
cursor.execute(sql, (NewRank, Findaname))
conn.commit()
If you do connect to a different database, call ATTACH. Here also, you can alias other database with better naming instead of number leading identifier.
cursor.execute("ATTACH '/path/to/0rk_D4T4B453.db' AS other_db")
sql = """UPDATE other_db.Da_Boyz
SET Rank = ?
WHERE Uzaname = ?"""
cursor.execute(sql, (NewRank, Findaname))
conn.commit()
cur.execute("DETACH other_db")
How to fix this error I use Python 3.6 and Database Oracle, I want to print data from databases, but shows errors, how can I fix it?
This is my databases:
enter image description here
EMPLOYEESID(Primary Key), NIK(Unique Key)
This is My code:
#import oracle module
import cx_Oracle
#membuat koneksi ke database oracle dan sesuaikan settingannya
con= cx_Oracle.connect("db_employees/root#localhost:1521/xe")
#inisialisasi cursor object methodnya
cur= con.cursor()
#eksekusi query
cur.execute('select*from employees')
#mengambil data dari query
rows = cur.fetchall()
#print data
for row in rows:
print('\nNIK : '+row[0])
print('Nama Karyawan : '+row[1])
print('Jabatan : '+row[3])
print('Birthdate : '+row[4])
print('Address : '+row[5]+ '\n')
#close cursor object
cur.close()
#close connection
con.close()
This is My Message Errors:
C:\Python36>python "D:\bisa.py"
Traceback (most recent call last):
File "D:\bisa.py", line 18, in <module>
print('\nNIK : '+row[0])
TypeError: must be str, not int
It is better to use string formatting instead of concatenation as you can't add a string with a number. Change the following line
print('\nNIK : '+row[0])
to
print('\nNIK : {}'.format(row[0]))
I'm working on a Python script that writes records from a stored procedure to a text file. I'm having issues executing the stored procedure with parameters.
I'm not sure what I could do differently to execute this stored procedure with both parameters. You can see the error I'm getting below.
Any insight would be appreciated.
Here's my code
# Import Python ODBC module
import pyodbc
# Create connection
cnxn = pyodbc.connect(driver="{SQL Server}",server="<server>",database="<database>",uid="<username>",pwd="<password>")
cursor = cnxn.cursor()
# Execute stored procedure
storedProc = "exec database..stored_procedure('param1', 'param2')"
# Loop through records
for irow in cursor.execute(storedProc):
# Create a new text file for each ID
myfile = open('c:/Path/file_' + str(irow[0]) + '_' + irow[1] + '.txt', 'w')
# Write retrieved records to text file
myfile.write(irow[2])
# Close the file
myfile.close()
Here's the error
Traceback (most recent call lst):
File "C:\Path\script.py", line 12, in <module>
for irow in cursor.execute(storedProc):
pyodbc.ProgrammingError: ('42000', "[4200] [Microsoft][ODBC SQL Server Driver][SQL Server]Incorrect syntax near 'param1'. <102> <SQLExecDirectW>">
I was able to fix the syntax error by removing the parenthesis from the query string.
# Execute stored procedure
storedProc = "exec database..stored_procedure('param1', 'param2')"
should be
# Execute stored procedure
storedProc = "exec database..stored_procedure 'param1','param2'"
This worked for me
query = "EXEC [store_proc_name] #param1='param1', #param2= 'param2'"
cursor.execute(query)
For SQL Server:
cursor.execute('{call your_sp (?)}',var_name)
I have some bulk postgresql 9.3.9 data inserts I do in python 3.4. I've been using SQLAlchemy which works fine for normal data processing. For a while I've been using psycopg2 so as to utilize the copy_from function which I found faster when doing bulk inserts. The issue I have is that when using copy_from, the bulk inserts fail when I have data that has got some special characters in it. When I remove the highlighted line the insert runs successfully.
Error
Traceback (most recent call last):
File "/vagrant/apps/data_script/data_update.py", line 1081,
in copy_data_to_db
'surname', 'other_name', 'reference_number', 'balance'), sep="|", null='None')
psycopg2.DataError: invalid byte sequence for encoding "UTF8": 0x00
CONTEXT:
COPY source_file_raw, line 98: "94|1|99|2015-09-03 10:17:34|False|True|John|Doe|A005-001\008020-01||||||..."
Code producing the error
cursor.copy_from(data_list, 'source_file_raw',
columns=('id', 'partner_id', 'pos_row', 'loaded_at', 'has_error',
'can_be_loaded', 'surname', 'other_name', 'reference_number', .............),
sep="|", null='None')
The db connection
import psycopg2
pg_conn_string = "host='%s' port='%s' dbname='%s' user='%s' password='%s'"
%(con_host, con_port, con_db, con_user, con_pass)
conn = psycopg2.connect(pg_conn_string)
conn.set_isolation_level(0)
if cursor_type == 'dict':
cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
else:
cursor = conn.cursor()
return cursor
So the baffling thing is that SQlAlchemy can do the bulk inserts even when those "special characters" are present but using psycopg2 directly fails. Am thinking there must be a way for me to escape this or to tell psycopg2 to find a smart way to do the insert or am I missing a setting somewhere?
I have a url which I want to save into the MySQL database using the "cursor" tool offered by django, but I keep getting the "not enough arguments for format string" error because this url contains some escaped characters (non-ascii characters). The testing code is fairly short:
test.py
import os
import runconfig #configuration file
os.environ['DJANGO_SETTINGS_MODULE'] = runconfig.django_settings_module
from django.db import connection,transaction
c = connection.cursor()
url = "http://www.academicjournals.org/ijps/PDF/pdf2011/18mar/G%C3%B3mez-Berb%C3%ADs et al.pdf"
dbquery = "INSERT INTO main_crawl_document SET url="+url
c.execute(dbquery)
transaction.commit_unless_managed()
The full error message is
Traceback (most recent call last):
File "./test.py", line 14, in <module>
c.execute(dbquery)
File "/usr/local/lib/python2.6/site-packages/django/db/backends/util.py", line 38, in execute
sql = self.db.ops.last_executed_query(self.cursor, sql, params)
File "/usr/local/lib/python2.6/site-packages/django/db/backends/__init__.py", line 505, in last_executed_query
return smart_unicode(sql) % u_params
TypeError: not enough arguments for format string
Can anybody help me?
You're opening yourself up for a possible SQL injection. Instead, use c.execute() properly:
url = "http://www.academicjournals.org/ijps/PDF/pdf2011/18mar/G%C3%B3mez-Berb%C3%ADs et al.pdf"
dbquery = "INSERT INTO main_crawl_document SET url=?"
c.execute(dbquery, (url,))
transaction.commit_unless_managed()
The .execute method should accept an iterable of parameters to use for escaping, assuming it's the normal dbapi method (which it should be with Django).