I have
cursor.execute("select RM_ID FROM Sales.dbo.MARKETING where VERSION = 'SomeVersion'")
which gives me the traceback error:
pyodbc.ProgrammingError: ('42S02', "[42S02] [Microsoft][ODBC SQL Server Driver][SQL Server]Invalid object name 'Sales.dbo.MARKETING'. (208) (SQLExecDirectW)")
I have several other lines of code:
cursor.execute("select RUNDATEEST FROM Sales.dbo.MARKETING where VERSION = 'SomeVersion'")
that are exactly the same except for the column name that give me no error. I'm not sure what my mistake is.
Of note:
I have already checked the table for the column name to make sure it exists.
I have noticed that this column is the key for this table. Perhaps a different syntax is required for keys?
When I execute the query in SQL Server, it runs just fine.
Try to surround schema and table names with brackets:
[Sales].[dbo].[MARKETING]
Perhaps you need to surround column names in the same way.
Related
cnxn = pyobdc.connect(...)
cursor = cnxn.cursor()
sql = 'create table if not exists tab1 (id integer primary key, entry varchar (200), exit varchar (200))'
cursor.execute(sql)
cnxn.commit()
in the above code, the query "sql" has the keyword "exit" as a column name which throws up an error. I therefore made the change of enclosing the keyword in quotes like
sql = 'create table if not exists tab1 (id integer primary key, entry varchar (200), "exit" varchar (200))'
and even tried
sql = 'create table if not exists tab1 (id integer primary key, entry varchar (200), `exit` varchar (200))'
Which still gives me the error:
ProgrammingError: ('42000', "[42000] [Microsoft][ODBC SQL Serveer Driver][SQLServer]Incorrect syntax near '"'. (102) (SQLExecDirectW)")
or accordingly,
ProgrammingError: ('42000', "[42000] [Microsoft][ODBC SQL Serveer Driver][SQLServer]Incorrect syntax near '`'. (102) (SQLExecDirectW)")
Please help me understand how to overcome this problem without having to change the column name, thanks!
As I said in the comments, firstly SQL Server does not support CREATE TABLE IF NOT EXISTS. See this question for specific answers on that.
Next your second statement. This won't generate the error you describe. In fact, if you do try to run it, you get the errors:
Incorrect syntax near the keyword 'if'.
Incorrect syntax near 'tab1'.
Again, this is because of comment 1. If you try the latter statement, with the backticks (`) you get the same identical errors, you don't get the error about the backtick. Though, as I also mentioned, the backticks are not a valid delimit identifier in T-SQL. Either use T-SQL own, brackets ([]), or ANSI SQLs, double quotes (").
Finally, to fix the problem, just don't use a reserved keyword for your object name. Perhaps something like this:
IF OBJECT_ID(N'dbo.tab1') IS NULL CREATE TABLE tab1 (id integer PRIMARY KEY, UserEntry varchar (200), UserExit varchar (200));
I get error using python 3.8.5
( cursor.execute("INSERT INTO dbo.sftpserverlist(FileName,FileSize) VALUES ("+files[0]+","+str(sizes[0])+")")
pyodbc.ProgrammingError: ('42000', '[42000] [Microsoft][ODBC SQL Server Driver][SQL Server]The multi-part identifier "DidosSupply.zip" could not be bound. (4104) (SQLExecDirectW)')
while I am trying call following function and insert into table dbo.sftpserverlist.
def getfile(sftp):
FileNames=[]
FileName = sftp.listdir_attr()
for i in FileName:
FileNames.append(i.filename)
FileSizes=[]
FileSize = sftp.listdir_attr()
for i in FileSize:
FileSizes.append(i.st_size)
return FileNames,FileSizes
-----------------------------------------------------------
cursor.execute("INSERT INTO dbo.sftpserverlist(FileName,FileSize) VALUES ("+files[0]+","+str(sizes[0])+")")
conn.commit()
Parametrise your query, don't inject the values, which is a huge security flaw.
cursor.execute("INSERT INTO dbo.sftpserverlist(FileName,FileSize) VALUES (?,?)",files[0],str(sizes[0]))
conn.commit()
cursor.close()
The reason you were getting the error was because the values you were (insecurely) injecting weren't quoted; thus the value of files[0] (which in this case had the value "DidosSupply.zip") was being interpreted as a column's name; which it can't be as you're within a VALUES clause with no FROM.
Of course, just wrapping quotes around the value isn't the solution, as quotes can be escaped.
I'm not an expert with Python, by any means, but I think this is the old-school way of doing it (INSERT INTO). I recently stumbled upon a super-easy, scalable, and controllable, way of pushing data from Python to SQL Server. Try the sample code and post back if you have additional questions.
import pyodbc
import pandas as pd
engine = "mssql+pyodbc://your_server_name/your_database_name?driver=SQL Server Native Client 11.0?trusted_connection=yes"
... dataframe here...
dataframe.to_sql(x, engine, if_exists='append', index=True)
dataframe is pretty self explanatory.
x = the name yo uwant your table to be in SQL Server.
I keep running into an error and cannot seem to find a solution anywhere online. I currently have a SQL that has 36 columns and am using a delete statement then inserting new values each day via a CSV and python program. It is a basic Insert Into statement that is utilizing a python for loop to insert all rows from the CSV.
I just added a new column to the SQL table and to my insert statement within the python program (I have done this multiple times to this same table in the past), however whenever I the new insert statement program I get the following error:
pyodbc.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC SQL Server
Driver][SQL Server]Incorrect syntax near '#P26'. (102) (SQLExecDirectW);
[42000] [Microsoft][ODBC SQL Server Driver][SQL Server]Statement(s) could
not be prepared. (8180)")
I assume the '#P26' is referring to some parameter, however I am not utilizing any SQL Parameters. Below is a snippet of my Python / SQL code:
SQL = """insert into example_table( [Column_1],
[Column_2],
[Column_3],
[Column_4],
[Column_5],
[Column_6],
[Column_7],
[Column_8],
[Column_9],
[Column_10],
....
[Column_36],
[New Column]
) values (?,?,?,?,?,?,?,?,?,?,?,?,
?,?,?,?,?,?,?,?,?,?,?,?,
?,?,?,?,?,?,?,?,?,?,?,?,?)"""
cursor2.execute("delete example_table")
for row in csv_data:
cursor2.execute(SQL, row)
Thanks so much for the help I am completely stuck. Sorry for the weird indents in the code. (NOTE: I know the syntax is correct as it works when I delete the new column and parameter marker and re-run).
This is a syntax issue, please check your "?" 26th value. This happen to me i has this syntax:
.... ?,?,?.?)
this was my 23th value and the error told me #P23.
Source: exp.
I have a python script that makes a call to an API, submits a request, and then is supposed to insert the result into a Sql Server 2012 table. When it goes to execute the insert into SQL, it breaks. I am currently importing json, requests, and pyodbc into the file. Here is the location where it is breaking:
conn = pyodbc.connect('DRIVER={SQL Server};SERVER={localServer};DATABASE={localDB}')
cursor = conn.cursor()
for record in response:
print(json.dumps(record))
cursor.execute("Insert Into Ticket_Info values ?", json.dumps(record))
cursor.commit()
cursor.close()
conn.close()
It is at the cursor.execute() line where the breakage occurs. This is the error I got when I attempted to run this.
pyodbc.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC SQL
Server Driver][SQL Server]Incorrect syntax near '#P1'. (102)
(SQLExecDirectW); [42000] [Microsoft][ODBC SQL Server Driver][SQL
Server]Statement(s) could not be prepared. (8180)"
Any help I could get I would appreciate. I have searched and tried several different methods at this point, the only thing that changes is the error.
The second argument to cursor.execute() must be a sequence of values to interpolate, one for each SQL parameter in your statement.
You gave ODBC a string instead, which is also a sequence, but one that contains (many) more elements (characters) than your query requires.
Use a single-element tuple here:
cursor.execute("Insert Into Ticket_Info values (?)", (json.dumps(record),))
I also put parenthesis around the values section, as per the SQL Server INSERT syntax:
VALUES
Introduces the list or lists of data values to be inserted. There must be one data value for each column in column_list, if specified, or in the table. The value list must be enclosed in parentheses.
Unless Ticket_Info has only one column per row (unlikely, you'd have a primary key column at least), you probably need to specify what column you are inserting your value into:
cursor.execute("Insert Into Ticket_Info (<columnname>) values (?)", (json.dumps(record),))
where you need to replace <columnname> with the actual column name in your table.
The problem is that I can't create a field named Date (I think because its a type)
Any ideas how to do that?
from pyodbc import connect
# database connect
conn = connect('DRIVER={Microsoft Access Driver (*.mdb)};DBQ=test.mdb')
cursor = conn.cursor()
# sql query execute
query = "create table MyTable(name varchar(30), age integer , Date date)"
cursor.execute(query)
# commit changes
conn.commit()
conn.close()
Error:
Traceback (most recent call last):
File "\Path\to\myscript\test.py", line 9, in <module>
cursor.execute(query)
ProgrammingError: ('42000', '[42000] [Microsoft][ODBC Microsoft Access Driver] Syntax error in field definition. (-3553) (SQLExecDirectW)')
Environment: Windows 7 64bit, Python 2.7 pyodbc-3.0.6.win-amd64-py2.7
DATE is a reserved word in Access (and other software).
Try wrapping the Date column name with square brackets [], or better yet, come up with a different column name.
...
query = "create table MyTable(name varchar(30), age integer , [Date] date)"
...
Surround the name in backticks the ` symbol. But, I would highly suggest changing the name to something else to prevent typos from happening.
You're right, you can't create a column with the same name as type. Some RDBMS's will allow you to do this if you quote it, i.e. "..age integer, "Date" date)" (or as others have said, backticks or square brackets) but then you have to quote it in all your queries as well. Better to avoid that.
Note that this isn't a python problem, it's a problem with the database server (which appears to be MS Access). (And to be accurate, it's not a problem with the database server, that's just how it works. It just has nothing to do with python.)