Python PYODBC INSERT - Too Few Parameters - python-3.x

I've been over this multiple times, I've taken a copy of the database file for testing purposes and even renamed the field to match the Python script. So the field name I am using in Python matches the tables field name exactly.
import pyodbc
def main():
tble="SomeTable"
fld1="SomeField"
val1="TestValue"
sqlStrng = """INSERT INTO %s (%s) VALUES(%s);""" %(tble, fld1,val1)
contStrng = (
r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};'
r'DBQ=Some\Path\File.accdb;'
)
cnnctn = pyodbc.connect(contStrng)
cursr = cnnct.cursor()
cursr.execute(sqlStrng)
cnnctn.commit()
cnnctn.close()
This isn't a spelling issue. I've made a testing copy of the Access file and created a table called SomeTable with a field called SomeField. I have the correct path, I've verified this by running a SELECT SQL script, which works without issue.
I've tried making fld1 a parameter and then sending that with the execute command, but then I'm informed I need 0 parameters. When I remove it, I'm informed I need 1.
I'm beginning to think perhaps it's this file? The same code works on another file I have. However I created a brand new file, and same results. I have to be missing something.

If you print(sqlStrng) immediately after assigning it you'll see that its value is
INSERT INTO SomeTable (SomeField) VALUES(TestValue);
The Access Database Engine treats unrecognized names as parameters, so it wants to be given a parameter value for name TestValue. If you want to insert the string value 'TestValue' then you should use a pyodbc parameter placeholder (?) and pass val1 as a parameter in the .execute method, like so:
tble="SomeTable"
fld1="SomeField"
val1="TestValue"
sqlStrng = """INSERT INTO [%s] ([%s]) VALUES(?);""" %(tble, fld1)
contStrng = (
r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};'
r'DBQ=Some\Path\File.accdb;'
)
cnnctn = pyodbc.connect(contStrng)
cursr = cnnct.cursor()
cursr.execute(sqlStrng, val1)
Notice that you wouldn't get an error if SomeField was a Number field and you used val1=123 because 123 would be treated as a numeric literal, not an unrecognized name (unquoted text value).

Related

Trying to extract data through bind variables in cx_oracle python

I am trying execute below block of code with cx_oracle by bind variables, but getting below mentioned error everytime. Not sure what is missing.
Anyone has idea on this
Code :
a = input("Please enter your name ::")
conn = cx_Oracle.connect('hello/123#oracle')
cur = conn.cursor()
text1 = "select customer from visitors where name = :myvalue;"
cur.execute(text1,myvalue=str(a))
ERROR observed :
cx_Oracle.DatabaseError: ORA-00933: SQL command not properly ended
Remove the semi-colon at the end of your SQL statement.

When to use SQL Foreign key using peewee?

I'm currently using PeeWee together with Python and I have managed to create a decent beginner
CREATE TABLE stores (
id SERIAL PRIMARY KEY,
store_name TEXT
);
CREATE TABLE products (
id SERIAL,
store_id INTEGER NOT NULL,
title TEXT,
image TEXT,
url TEXT UNIQUE,
added_date timestamp without time zone NOT NULL DEFAULT NOW(),
PRIMARY KEY(id, store_id)
);
ALTER TABLE products
ADD CONSTRAINT "FK_products_stores" FOREIGN KEY ("store_id")
REFERENCES stores (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE RESTRICT;
which has been converted to peewee by following code:
# ------------------------------------------------------------------------------- #
class Stores(Model):
id = IntegerField(column_name='id')
store_name = TextField(column_name='store_name')
class Meta:
database = postgres_pool
db_table = "stores"
#classmethod
def get_all(cls):
try:
return cls.select(cls.id, cls.store_name).order_by(cls.store)
except Stores.IntegrityError:
return None
# ------------------------------------------------------------------------------- #
class Products(Model):
id = IntegerField(column_name='id')
store_id = TextField(column_name='store_id')
title = TextField(column_name='title')
url = TextField(column_name='url')
image = TextField(column_name='image')
store = ForeignKeyField(Stores, backref='products')
class Meta:
database = postgres_pool
db_table = "products"
#classmethod
def get_all_products(cls, given_id):
try:
return cls.select().where(cls.store_id == given_id)
except Stores.IntegrityError:
return None
#classmethod
def add_product(cls, pageData, store_id):
"""
INSERT
INTO
public.products(store_id, title, image, url)
VALUES((SELECT id FROM stores WHERE store_name = 'footish'), 'Teva Flatform Universal Pride',
'https://www.footish.se/sneakers/teva-flatform-universal-pride-t51116376',
'https://www.footish.se/pub_images/large/teva-flatform-universal-pride-t1116376-p77148.jpg?timestamp=1623417840')
"""
try:
return cls.insert(
store_id=store_id,
title=pageData.title,
url=pageData.url,
image=pageData.image,
).execute()
except Products.DoesNotExist:
return None
except peewee.IntegrityError as err:
print(f"error: {err}")
return None
My idea is that when I start my application, I would have a constant variable which a store_id set already e.g. 1. With that it would make the execution of queries faster as I do not need another select to get the store_id by a store_name. However looking at my code. I have a field that is: store = ForeignKeyField(Stores, backref='products') where I am starting to think what do I need it in my application.
I am aware that I do have a FK from my ALTER query but in my application that I have written I cannot see a reason why I would need to type in the the foreign key at all but I would like some help to understand more why and how I could use the value "store" in my applciation. It could be as I think that I might not need it at all?
Hello! By reading your initial idea about making "the execution of queries faster" from having a constant variable, the first thing that came to mind was the hassle of always having to manually edit the variable. This is poor practice and not something you'd want to do on a professional application. To obtain the value you should use, I suggest running a query programmatically and fetching the id's highest value using SQL's MAX() function.
As for the foreign key, you don't have to use it, but it can be good practice when it matters. In this case, look at your FK constraint: it has an ON DELETE RESTRICT statement, which cancels any delete operation on the parent table if it has data being used as a foreign key in another table. This would require going to the other table, the one with the foreign key, and deleting every row related to the one on the previous table before being able to delete it.
In general, if you have two tables with information linked in any way, I'd highly suggest using keys. It increases organization and, if proper constraints are added, it increases both readability for external users and reduces errors.
When it comes to using the store you mentioned, you might want to have an API return all products related to a single store. Or all products except from a specific one.
I tried to keep things simple due to not being fully confident I understood the question. I hope this was helpful.

Groovy assertion on SOAP UI for database output

Using SOAP UI I am running query and fetching data for an specific ID and after that I want to validate specific field and its corresponding Value which is returning .
Ex -
Version =2
So I want to validate that every time for the generated record the version is 2 .
I checked and came up with the below code but the Select query is giving me error ,where it is unable to read value returning from recordId variable which i am using in Where condition ,So how to resolve it ?
The below is the database result which i want to validate
here
def listOfPostedRecordIds = parser.parseText(context.expand( '${1.CreateTestData#IdsToBeDeleted}' ))
def **recordId**=listOfPostedRecordIds[0]
log.info "recordId is "+recordId
def Version = myDB.firstRow('''Select cast(("Research"."meta"#>>'{versionId}') as integer)as Version from "Research"where id= **("recordId")** ''')
log.info "The value of is ${Version}
To parameterize data in your SQL in Groovy, do it with a ? like this:
def recordId = listOfPostedRecordIds[0]
def Version = myDB.firstRow("""
Select cast(('ResearchSubject'.'meta'#>>'{versionId}') as integer) as Version
from 'ResearchSubject'
where id = ?;""", [recordId])
log.info "The value of is ${Version}"
Also note that your select is quite complicated with ", ', # >> and {}. Make sure all those are really required.

Reading blob from database without saving to disk in Python

I am trying to read a set of records from db which has a blob field. I am able to read it but not without saving it to disk first.
cursor.execute("select image ,id,
department from dept_master")
depdata = cursor.fetchall()
for row in depdata:
file_like = io.BytesIO(row[0])
file = PIL.Image.open(file_like)
target = os.path.join("/path-to-save/", 'folder-save')
destination = "/".join([target, file.filename])
file.save(destination)
How can I read it and display it without first saving to disk ?
I am planning to use render_template to display the data
To serve the images from a blob field, you need to create a separate route which serves the actual image data specifically, then in a template include links which load the files from this route.
There's no need to use PIL here, as the blob field gives you bytes data. You run that through BytesIO to get a _io.BytesIO object, which can be passed straight to Flask's send_file function.
from io import BytesIO
from flask import send_file
#app.route('/image/<int:ident>')
def image_route(ident):
# This can only serve one image at a time, so match by id
cursor.execute("select image from dept_master WHERE id = ?", (ident,)
result = cursor.fetchone()
image_bytes = result[0]
bytes_io = BytesIO(image_bytes)
return send_file(bytes_io, mimetype='image/jpeg')
At this stage you should be able to hit /image/1 and see the image in your browser for the row with id 1.
Then, somewhere in a template, just include the link for this with:
<img src='{{ url_for("image_route", ident=image_ident) }}' />
This assumes that image_ident is available in the template. You might need to replace this variable name with something which exsists (could be a variable within a for loop which denotes the image id to pull).
Let me know if this needs further explaining.

Why is named parameter 'not defined'?

Trying to use a named parameter in a simple sql query. Upon assigning a value to the parameter, the marameter name is flagged as undefined (NameError)
Same query works fine with positional parameter
Tried over different tables with different parameter names
Passed values directly rather than via variables
import sqlite3
myConn = sqlite3.connect("testDB.db")
myCursor = myConn.cursor()
myCursor.execute(
"SELECT CourseName FROM Courses WHERE CourseName =:course",{'English':course})
print(myCursor.fetchone())
I should retrieve just the one line from the db.
instead I get the following error message
line 14, in <module>
myCursor.execute("SELECT CourseName FROM Courses WHERE CourseName =:course",{'English':course})
NameError: name 'course' is not defined
The secon argument ot the execute query is a dictionary. The key is the named parameter used in the SQL query (it needs too be in btw quotes) the value for that key is a variable instantiaded somewhere else in the code.
import sqlite3
myConn = sqlite3.connect("testDB.db")
myCursor = myConn.cursor()
query = "SELECT CourseName FROM Courses WHERE CourseName=:course"
test = "English"
myCursor.execute("SELECT CourseName FROM Courses WHERE CourseName =:course",{'course':test})
print(myCursor.fetchone())

Resources