I am completely lost here:
v_sql = "SELECT widget_name, widget_url FROM widget_calls WHERE widget_name = :widget"
cursor.execute(v_sql, widget=widget_name)
df_wid = pd.read_sql(v_sql, con=connection)
Result:
pandas.io.sql.DatabaseError: Execution failed on sql 'SELECT widget_name, widget_url FROM widget_calls WHERE widget_name = :widget': ORA-01008: not all variables bound
There is 1 bind variable, :widget, and 1 declaration in the execute. So, what am I missing?
The cursor.execute call and the pd.read_sql call are completely unrelated. You're doing the query twice, and throwing away the first result. I would delete the useless cursor.execute.
And for read_sql, you need:
df_wid = pd.read_sql( v_sql, con=connection, params={'widget': widget_name})
Related
I have this code segment in Python2:
def super_cool_method():
con = psycopg2.connect(**connection_stuff)
cur = con.cursor(cursor_factory=DictCursor)
cur.execute("Super duper SQL query")
rows = cur.fetchall()
for row in rows:
# do some data manipulation on row
return rows
that I'd like to write some unittests for. I'm wondering how to use mock.patch in order to patch out the cursor and connection variables so that they return a fake set of data? I've tried the following segment of code for my unittests but to no avail:
#mock.patch("psycopg2.connect")
#mock.patch("psycopg2.extensions.cursor.fetchall")
def test_super_awesome_stuff(self, a, b):
testing = super_cool_method()
But I seem to get the following error:
TypeError: can't set attributes of built-in/extension type 'psycopg2.extensions.cursor'
You have a series of chained calls, each returning a new object. If you mock just the psycopg2.connect() call, you can follow that chain of calls (each producing mock objects) via .return_value attributes, which reference the returned mock for such calls:
#mock.patch("psycopg2.connect")
def test_super_awesome_stuff(self, mock_connect):
expected = [['fake', 'row', 1], ['fake', 'row', 2]]
mock_con = mock_connect.return_value # result of psycopg2.connect(**connection_stuff)
mock_cur = mock_con.cursor.return_value # result of con.cursor(cursor_factory=DictCursor)
mock_cur.fetchall.return_value = expected # return this when calling cur.fetchall()
result = super_cool_method()
self.assertEqual(result, expected)
Because you hold onto references for the mock connect function, as well as the mock connection and cursor objects you can then also assert if they were called correctly:
mock_connect.assert_called_with(**connection_stuff)
mock_con.cursor.asset_called_with(cursor_factory=DictCursor)
mock_cur.execute.assert_called_with("Super duper SQL query")
If you don't need to test these, you could just chain up the return_value references to go straight to the result of cursor() call on the connection object:
#mock.patch("psycopg2.connect")
def test_super_awesome_stuff(self, mock_connect):
expected = [['fake', 'row', 1], ['fake', 'row' 2]]
mock_connect.return_value.cursor.return_value.fetchall.return_value = expected
result = super_cool_method()
self.assertEqual(result, expected)
Note that if you are using the connection as a context manager to automatically commit the transaction and you use as to bind the object returned by __enter__() to a new name (so with psycopg2.connect(...) as conn: # ...) then you'll need to inject an additional __enter__.return_value in the call chain:
mock_con_cm = mock_connect.return_value # result of psycopg2.connect(**connection_stuff)
mock_con = mock_con_cm.__enter__.return_value # object assigned to con in with ... as con
mock_cur = mock_con.cursor.return_value # result of con.cursor(cursor_factory=DictCursor)
mock_cur.fetchall.return_value = expected # return this when calling cur.fetchall()
The same applies to the result of with conn.cursor() as cursor:, the conn.cursor.return_value.__enter__.return_value object is assigned to the as target.
Since the cursor is the return value of con.cursor, you only need to mock the connection, then configure it properly. For example,
query_result = [("field1a", "field2a"), ("field1b", "field2b")]
with mock.patch('psycopg2.connect') as mock_connect:
mock_connect.cursor.return_value.fetchall.return_value = query_result
super_cool_method()
The following answer is the variation of above answers.
I was using django.db.connections cursor object.
So following code worked for me
#patch('django.db.connections')
def test_supercool_method(self, mock_connections):
query_result = [("field1a", "field2a"), ("field1b", "field2b")]
mock_connections.__getitem__.return_value.cursor.return_value.__enter__.return_value.fetchall.return_value = query_result
result = supercool_method()
self.assertIsInstance(result, list)
#patch("psycopg2.connect")
async def test_update_task_after_launch(fake_connection):
"""
"""
fake_update_count =4
fake_connection.return_value = Mock(cursor=lambda : Mock(execute=lambda x,y :"",
fetch_all=lambda:['some','fake','rows'],rowcount=fake_update_count,close=lambda:""))
Upon closing a connection, deletion done by stored procedure DeleteSproc is getting rolled back. What's wrong with this code?
try:
sql = '{CALL dbo.DeleteSproc (?,?,?,?,?,?,?,?)}'
values = (c['brandId'],c['requestUuid'],c['registrationUuid'],i['tuid'],i['tpid'],c['status'],c['responseType'],i['BookingItemIds'])
connBS = pyodbc.connect(l['connectionStrings'][0])
cursorBS = connBS.cursor()
rv = cursorBS.execute(sql, values)
sql = '{CALL dbo.StatusProc (?,?,?)}'
values = (c['requestUuid'],i['tuid'],i['tpid'])
cursorBS.execute(sql, values)
rows = cursorBS.fetchall()
finally:
cursorBS.close()
connBS.close()
I was able to solve this by putting COMMIT at the end of the stored procedure.
I am trying to use a tkinter option menu to select the variable to search for in a table. A problem arises however as the passed variable does not yield any result.
Here is the table:
And here is proof that the SQL syntax is not incorrect.
The problem is due to the string variable being incorrect and returning:
[]
no data.
When I select a variable from the OptionMenu, instead of getting:
jhgfds
I get:
('jhgfds',)
So understandably I get no result.
I have tried using these methods on the :
Creating a non-tkinter variable (`StrEditEvent)
The re method
The [2:-3] method
However these have not worked
import tkinter as tk
import mysql.connector
root=tk.Tk()
EventList=[]
def OptionChanged(*args):
EventSQL=("SELECT * FROM events WHERE eventname=%s")
print(EditEvent.get())
StrEditEvent=EditEvent.get()
print(StrEditEvent)
mycursor.execute(EventSQL,(StrEditEvent,))
myresults=mycursor.fetchall()
print(myresults)
# Adding Tracking Variable EditEvent
EditEvent = tk.StringVar()
EditEvent.trace("w", OptionChanged)
#Connecting To My Database
mydb = mysql.connector.connect(
host="localhost",
user="root",
passwd="Cranmore1",
database="scoutsdatabase"
)
print(mydb)
mycursor = mydb.cursor()
mycursor.execute("SELECT eventname FROM events")
myresults=mycursor.fetchall()
for i in myresults:
EventList.append(i)
EventToEditOptionMenu = tk.OptionMenu(root,EditEvent,*EventList)
EventToEditOptionMenu.grid(row=1,column=1)
root.mainloop()
Any help would be greatly appreciated.
print(EventList)
[('jhgfds',), ('uytrds',), ('sadfghjk',), ('jhytre',), ('j',), ('h',), ('q',), ('BBC',), ('BBC',), ('qwed',)]
To get the result as jhgfds you need to iterate over it because it returns the result for the query as a tuple [('jhgfds',), ('uytrds',), ('sadfghjk',), ('jhytre',), ('j',), ('h',), ('q',), ('BBC',), ('BBC',), ('qwed',)]
You can use index to get the specific result you want result[0] or result[2]
def OptionChanged(*args):
EventSQL=("SELECT * FROM events WHERE eventname=%s")
print(EditEvent.get())
StrEditEvent=EditEvent.get()
print(StrEditEvent)
mycursor.execute(EventSQL,(StrEditEvent,))
myresults=mycursor.fetchall()
for result in myresults: # iterate over it
print(result)
print(result[2])
print(result[5])
I've finally worked out the answer! To obtain the string from the tuple, one must use the map() command.
def OptionChanged(*args):
EventSQL=("SELECT * FROM events WHERE eventname=%s")
StrEditEvent=EditEvent.get()
start,mid,end=map(str,StrEditEvent.split("'"))
print(mid)
mycursor.execute(EventSQL,(mid,))
myresults=mycursor.fetchall()
print(myresults)
Thus ('jhgfds',) is converted into jhgfds so the SQL query finds the data from the database.
I have a custom function in Oracle Locator and I will use this function inside cx_Oracle to transform my SDO_Geometry in GeoJSON!
import cx_Oracle
import json
connection = cx_Oracle.Connection("TEST_3D/limo1013#10.40.33.160:1521/sdetest")
cursor = connection.cursor()
cursor.execute("""SELECT a.id AS building_nr, c.Geometry AS geometry, d.Classname AS polygon_typ FROM building a, THEMATIC_SURFACE b, SURFACE_GEOMETRY c, OBJECTCLASS d WHERE a.grid_id_400 = 4158 AND a.id = b.BUILDING_ID AND b.LOD2_MULTI_SURFACE_ID = c.ROOT_ID AND c.GEOMETRY IS NOT NULL AND b.OBJECTCLASS_ID = d.ID""")
obj = cursor.fetchone()
obj = obj[1]
print obj
result = cursor.callfunc('sdo2geojson', cx_Oracle.OBJECT, [obj])
My object looks like : cx_Oracle.OBJECT.
This function is working inside SQLdeveloper.
When I call the function I get the following error: cx_Oracle.NotSupportedError: Variable_TypeByValue(): unhandled data type cx_Orac
le.OBJECTVAR
What I´m doing wrong???
This capability is available in the currently unreleased version of cx_Oracle. You can get the source from https://bitbucket.org/anthony_tuininga/cx_oracle.
I am attempting to figure out how to use the IN keyword in a django model query.
I was attempting to replace:
db = database.connect()
c = db.cursor()
c.execute("SELECT MAX(Date) FROM `Requests` WHERE UserId = %%s AND VIN = %%s AND Success = 1 AND RptType in %s" % str(cls.SuperReportTypes), (userID, vin))
With this:
myrequests = Request.objects.filter(user=userID, vin = vin, report_type in cls.SuperReportTypes)
myrequests.aggregate(Max('Date'))
I get a:
SyntaxError: non-keyword arg after keyword arg (<console>, line 1)
When I remove the ending "report_type in cls.SuperReportTypes" the query functions properly.
I recognize that there is a way to do this after the query managing the result set but I was hoping to deal with this in such a way that MYSQL would do the execution.
field__in=seq
You are using the wrong in statement
https://docs.djangoproject.com/en/dev/ref/models/querysets/#in