Can't upload Images to MS Sql server via pyodbc - python

i'm trying to upload an image to MS SQL web-server in Linux(raspbian) environment using python language. so far i had able connect to MS Sql and also i had create a table. And im using pyodbc.
#! /user/bin/env python
import pyodbc
dsn = 'nicedcn'
user = myid
password = mypass
database = myDB
con_string = 'DSN=%s;UID=%s;PWD=%s;DATABASE=%s;' % (dsn, user, password, database)
cnxn = pyodbc.connect(con_string)
cursor = cnxn.cursor()
string = "CREATE TABLE Database1([image name] varchar(20), [image] varbinary(max))"
cursor.execute(string)
cnxn.commit()
this part complied without any error. that means i have successfully created a table isn't? or is there any issue?
i try to upload image as this way.
with open('new1.jpg','rb') as f:
bindata = f.read()
cursor.execute("insert into Database1(image name, image) values (?,?)", 'new1', bindata)
cnxn.commit()
i get the error on this part. and it pyodbc.ProgrammingError: ('42000', '[42000] [FreeTDS] [SQL Server] Satement(s) could not be prepared. (8180) (SQLParamData)')
can some one help me please. thank you

Your parameters must be passed in as one sequence, not as two separate arguments. A tuple will do nicely here:
cursor.execute(
"insert into Database1([image name], image) values (?,?)",
('new1', pyodbc.Binary(bindata)))
Note that you also need to quote the image name column correctly, and wrap the data in a pyodbc.Binary() object; this will produce the right datatype for your Python version (bytearray or bytes).

Related

How to commit stored procedure execution by using pyodbc

I am trying to execute stored procedure by using pyodbc in databricks, after executing SP I tried to commit the connection but, commit is not happening. Here I am giving my code, please help me out from this issue.
import pyodbc
#### Connecting Azure SQL
def db_connection():
try:
username = "starsusername"
password = "password-db"
server = "server-name"
database_name = "db-name2"
port = "db-port"
conn=pyodbc.connect('Driver={ODBC Driver 17 for SQL server};SERVER=tcp:'+server+','+port+';DATABASE='+ database_name +';UID='+ username +';PWD='+ password)
cursor=conn.cursor()
return cursor, conn
except Exception as e:
print("Faild to Connect AZURE SQL: \n"+str(e))
cursor, conn = db_connection()
# conn1.autocommit=True
cursor.execute("delete from db.table_name")
cursor.execute("insert into db.table_name(BUSINESS_DATE) values('2021-10-02')")
cursor.execute("exec db.SP_NAME '20211023'")
conn.commit()
conn.close()
here I am commiting connection after SP excution. deletion and insertion is not happening at all. and I tried with cursor.execute("SET NOCOUNT ON; exec db.SP_NAME '20211023'") but it's also not working.
Thanks in Advance
If you check this document on pyodbc, you will find that -
To call a stored procedure right now, pass the call to the execute method using either a format your database recognizes or using the ODBC call escape format. The ODBC driver will then reformat the call for you to match the given database.
Note that after connection is set up or done, try doing conn.autocommit = True before calling your SP and it will help. By default it is false.
Executing the Stored Procedure.
You will be able to execute your stored procedure if you follow the below code snippet.
cursor = conn.cursor()
conn.autocommit = True
executesp = """EXEC yourstoredprocedure """
cursor.execute(executesp)
conn.commit()
Delete the Records in SQL Server
You can delete record as shown in the below example.
...#just an example
cursor.execute('''
DELETE FROM product
WHERE product_id in (5,6)
''')
conn.commit()
Don’t forget to add conn.commit() at the end of the code, to ensure that the command would get executed.
Insert record in SQL Server
The below snippet show how we can do the same.
...#just an example
cursor.execute("INSERT INTO EMP (EMPNO, ENAME, JOB, MGR) VALUES (535, 'Scott', 'Manager', 545)")
conn.commit()
I will suggest you to read the for following document for more information.
Delete Record Documentation.
Insert Record Document

Data Types problem while ingesting from Salesforce to Azure SQL using pyodbc in Python

I'm ingesting data from Salesforce to Azure SQL Database using Python with pyodbc.
I make a first connexion with Salesforce as shown bellow:
cnxn = pyodbc.connect('DRIVER={Devart ODBC Driver for Salesforce};User ID=xxx;Password=xxx;Security Token=xxx')
Then I import Salesforce data, as shown bellow:
cursor = cnxn.cursor()
cursor.execute("select * from X where Y > 'VALUE'")
row = cursor.fetchall()
After that I make a second connexion with the destination which is Azure SQL Database, as shown bellow:
cnxn = pyodbc.connect('DRIVER={Devart ODBC Driver for SQL Azure};Server=xxx;Database=xxx;Port=1433;User ID=xxx;Password=xxx')
Until now, everything is working fine. But when I try to insert the output that I got from Salesforce (in variable row) I face data type problems, from which we can cite:
Tabulations "\t"
Back to the line sign (in Azure SQL Database is CHAR(13) + CHAR(10) +)
Charaters that contains quote (e.g. "big data's technology")
Here is how I launch the insertion query:
cursor.executemany('INSERT INTO dbo.Account (Column_a,Column_b,Column_c) VALUES (?,?,?,?)', row)
cursor.commit()
Here is the first error I get:
pyodbc.Error: ('HY000', '[HY000] [Devart][ODBC][Microsoft SQL Azure]Statement(s) could not be prepared.\r\nMust declare the scalar variable "#_39".\r\nLine 1: Specified scale 14 is invalid. (0) (SQLExecDirectW)')
This issue was apparently caused by a defect in the
Devart ODBC Driver for SQL Azure
Using Microsoft's
ODBC Driver 17 for SQL Server
solved the problem .

Run the query saved in MS Access with required parameters through Pyodbc?

I am using Pyodbc to connect my program with MS Access. In the Access database, I pre-created some queries that require parameters. How can I pass values to parameters of the queries when executing them in Python?
When an Access database contains saved parameter queries they are exposed by Access ODBC as stored procedures and can be invoked using the ODBC {call ...} syntax. For example, with a saved query named [ClientEmails] ...
PARAMETERS prmLastName Text ( 255 );
SELECT Clients.ID, Clients.LastName, Clients.FirstName, Clients.Email
FROM Clients
WHERE (((Clients.LastName)=[prmLastName]));
... the following Python code will run that query and return results for a specific Last Name:
cmd = "{call ClientEmails(?)}"
params = ("Thompson",)
crsr.execute(cmd, params) # pyodbc "cursor" object
for row in crsr.fetchall():
print(row)
Here's a generalized example. First, connect to the database. Then, issue commands. The command is just a string. You can incorporate variables from elsewhere in your code through simple string concatenation.
import pyodbc
connStr = """
DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};
DBQ=C:\full\path\to\your\PYODBC.accdb;
"""
cnxn = pyodbc.connect(connStr)
cursor = cnxn.cursor()
desired_column = "Forename"
table_name = "Student"
command = "SELECT " + desired_column + " FROM " + table_name
cursor.execute(command)
row = cursor.fetchone()
if row:
print(row)

Updating SQL table using mysql python module

I am attempting to update a single value in a single cell in a SQL table using the mysql connector for python. Using the following code, I get no error messages, but nor does the table actually update. The value of the cell that I am attempting to update is sometimes empty, sometimes NULL, and sometimes contains a string. Here is my code:
query = ("UPDATE data_set SET %s = '%s' WHERE id = %s") % (column_to_change, change_to_value, row_id)
What am I doing wrong?
Edit: Thanks for the replies so far. I do not think there is any functional issue with the surrounding code (outside of the vulnerability to SQL injection, which I have fixed, here and elsewhere), as I have been effective executing similar code with different queries. Here is my code now:
column_to_change = "column2"
change_to_value = "james"
id = "1234"
cnx = mysql.connector.connect(user='user', password='password',
host='db.website.com',
database='database')
cursor = cnx.cursor()
query = ("UPDATE data_set SET %s = %s WHERE policy_key = %s")
cursor.execute(query, (column_to_change, change_to_value, id))
cursor.close()
cnx.close()
If it's relevant, it turns out the cells I'm trying to insert into are formatted as VARCHAR(45). When I run a SELECT query on a cell, it returns a name formatted like: (u'James',)
If I set change_to_value = "(u'James',)", I receive the following error message:
mysql.connector.errors.ProgrammingError: 1064 (42000): You have an error in your SQL syntac; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''column1' = '(u\'James\',)' WHERE id = '1234'' at line 1
Make sure you are following all the steps:
conn = pyodbc.connect("SERVER=my.server;DATABASE=my_database;UID=my_user;PWD=my_password;",ansi=True)
cursor = conn.cursor()
query = ("UPDATE data_set SET %s = '%s' WHERE id = %s") % (column_to_change, change_to_value, row_id)
cursor.execute(query)
And also verify the SQL query that your passing to .execute() is same as that you want to run on your database
Depending on your version of Python, perhaps it is an issue with your string interpolation. Otherwise, you may not be connecting your cursor and executing the query successfully. I am assuming you are executing your query elsewhere in your code, but in the instance you are not, this should work:
cursor.execute ("""
UPDATE data_set
SET %s=%s
WHERE id=%s
""", (column_to_change, change_to_value, row_id))
Alternatively, you could store this query in a variable as you have done, assign the respective variables and execute afterward like so:
query = (“UPDATE data_set SET %s=%s WHERE id=%s”)
column_to_change = [YOUR ASSIGNMENT HERE]
change_to_value = [YOUR ASSIGNMENT HERE--if this is a string, it should be formatted as such here]
row_id = [YOUR ASSIGNMENT HERE]
cursor.execute(query, (column_to_change, change_to_value, row_id))
Basic string interpolation is prone to SQL injection and should be avoided.
For more reference, see here

create a database using pyodbc

I am trying to create a database using pyodbc, however, I cannot find it seems to be paradox as the pyodbc needs to connect to a database first, and the new database is created within the linked one. Please correct me if I am wrong.
In my case, I used following code to create a new database
conn = pyodbc.connect("driver={SQL Server};server= serverName; database=databaseName; trusted_connection=true")
cursor = conn.cursor()
sqlcommand = """
CREATE DATABASE ['+ #IndexDBName +'] ON PRIMARY
( NAME = N'''+ #IndexDBName+''', FILENAME = N''' + #mdfFileName + ''' , SIZE = 4000KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
LOG ON
( NAME = N'''+ #IndexDBName+'_log'', FILENAME = N''' + #ldfFileName + ''' , SIZE = 1024KB , MAXSIZE = 100GB , FILEGROWTH = 10%)'
"""
cursor.execute(sqlcommand)
cursor.commit()
conn.commit()
The above code works without errors, however, there is no database created.
So how can I create a database using pyodbc?
Thanks a lot.
If you try to create a database with the default autocommit value for the connection, you should receive an error like the following. If you're not seeing this error message, try updating the SQL Server native client for a more descriptive message:
pyodbc.ProgrammingError: ('42000', '[42000] [Microsoft][SQL Server Native Client 11.0]
[SQL Server]CREATE DATABASE statement not allowed within multi-statement transaction.
(226) (SQLExecDirectW)')
Turn on autocommit for the connection to resolve:
conn = pyodbc.connect("driver={SQL Server};server=serverName; database=master; trusted_connection=true",
autocommit=True)
Note two things:
autocommit is not part of the connection string, it is a separate keyword passed to the connect function
specify the initial connection database context is the master system database
As an aside, you may want to check the #IndexDBName, #mdfFileName, and #ldfFileName are being appropriately set in your T-SQL. With the code you provided, a database named '+ #IndexDBName +' would be created.
The accepted answer did not work for me but I managed to create a database using the following code on Ubuntu:
conn_str = r"Driver={/opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.9.so.1.1};" + f"""
Server={server_ip};
UID=sa;
PWD=passwd;
"""
conn = pyodbc.connect(conn_str, autocommit=True)
cursor = conn.cursor()
cursor.execute(f"CREATE DATABASE {db_name}")
Which uses the default "master database" when connecting. You can check if the dataset is created by this query:
SELECT name FROM master.sys.databases

Categories

Resources