Consider you have the following code:
import pandas as pd
pd.read_sql("SELECT * FROM foo_schema.run_info WHERE id=:param order by run_id desc", s.bind, **{'param':5})
Whereas s.bind is sqlchemy's engine object.
I get the following error:
{TypeError}read_sql() got an unexpected argument 'param'
what is wrong with my function call?
From the docs,
pd.read_sql?
...
params : list, tuple or dict, optional, default: None
What you're doing is unpacking the dictionary, so it is passed as a keyword argument. See Understanding kwargs in Python for more information.
The correct way to pass parameters is:
pd.read_sql(... params={'param':5})
As #Ilja Everilä expertly mentioned, you should wrap your query inside a call to text in order to have the parameter syntax correctly parsed.
from sqlalchemy import text
pd.read_sql(text(query), s.bind, params={'param':5})
Related
I have been trying to run a parameterized query using the client libraries in Python and I have tried both the named parameters and the positional parameters methods in the documentation, but neither of them worked.
Here's the positional parameters method:
And the output:
The code compiles with no error when I remove the last line of code:
I have a different function that does not use a parameterized query and works just fine:
How can I parameterize it with "id"?
I have tried the named parameters and the positional parameters methods described in the documentation but neither of them worked. I'm expecting to get data for the specific id parameter and put it in a data frame.
Try removing squar brackets from table name clause.
change
select * from [ Table_name ]
to this
select * from Table_name
#python
sql="UPDATE bebliothequee SET title=:titl,author=:autho,ISBN=:ISB WHERE oid='{}'.format(oid.get())",title='{}'.format(title_editor.get()),author='{}'.format(author_editor.get()),ISBN='{}'.format(ISBN_editor.get()),oid='{}'.format(record_id.get())
Your first mistake is that you didn't read Stackoverflow documentation how to create good question. So you didn't add all details in question - and we can't read in your mind - and we can't help it.
Next mistake: you put code in comment but you should put it in question so it would be more readalbe but what is more important: all people could see it and help you.
Code shows that you try to create sql =... with all arguments for execute() and later use it in execute() but it doesn't work this way. You can't assing positional and named values to variable and later put it in function. You should use it directly in execute() or you should create list/tuple with positional variables and dictionary with named variables.
BTW: you don't need '{}'.format() to convert it to strings. You could use str() but I think execute() should convert it automatically.
query = "UPDATE bebliothequee SET title=:title, author=:author, ISBN=:ISBN WHERE oid=:oid"
execute(query, title=title_editor.get(), author=author_editor.get(), ISBN=ISBN_editor.get(), oid=record_id.get())
Other problem is that you use :titl but you should use full name :title like in argument title=....
You have also oid='{}'.format(oid.get() inside query which is totally useless.
BTW: Eventually you can create dictionary
args = {
'title': title_editor.get(),
'author', author_editor.get(),
'ISBN': ISBN_editor.get(),
'oid': record_id.get(),
}
and then you can use ** to unpack it as named arguments
execute(query, **args)
Since from is a special python keyword I am not able to pass it pyes.es.search function. It give syntax error. pyes.es.search(maf, "twitter", "tweet", sort="timestamp", size=2, from=3) . I passed keyword arguments containing from also as below but from did not work while other worked.
keywords = {'sort': 'timestamp', 'size':3, 'from':2}
r = pyes.es.search(maf, "twitter", "reply",**keywords)
This problem also available for another python elasticsearch module here here. In search function interface there is from argument.
Did you try with start parameter?
It sounds like the one to use.
See http://pyes.readthedocs.org/en/latest/references/pyes.queryset.html#pyes.queryset.QuerySet.start
Can I implement the following in SQLAlchemy,
SELECT *
FROM TABLE
WHERE RIGHT(COLUMN_CODE, 2) = 'AX'
here RIGHT( ) returns the right part of a character string with the specified number of characters.
Is there a SQLAlchemy implementation of the RIGHT function?
You'd be better off using the .endswith() method instead:
select([tabledef]).where(tabledef.c.column_code.endswith('AX'))
or, when filtering with a mapper config and a session:
session.query(mappedobject).filter(mappedobject.column_code.endswith('AX'))
The column_code.endswith() method will be translated to whatever SQL is best for your particular engine, matching column values that end with AX.
You can always use the function generator to create arbitrary SQL functions if you have to use the RIGHT() sql function directly:
from sqlalchemy.sql.expression import func
select([tabledef]).where(func.right(tabledef.c.column_code, 2) == 'AX')
and the func.right() call will be translated to RIGHT(column_code, 2) by the SQL generation layer.
The documentation does not make it clear, but you can write any function using func.funcname sytle. funcname does not have to be defined natively by SQLAlchemy module. SQLAlchemy knows about common functions like min, max etc. and if there is dialect to dialect variation amongst those functions, SQLAlchemy takes care of that for you.
But the functions that SQLAlchemy does not know about are passed as is. So you can create your query that generates a SQL statement with the required RIGHT function like so
>>> from sqlalchemy import func
>>> select([table]).where(func.RIGHT(users.c.column_code, 2)='AX')
I'm trying to use the Connection.set_authorizer method to only allow certain DB operations with a connection object. (The documentation is here)
I'm using this code to test:
import sqlite3 as sqlite
def select_authorizer(sqltype, arg1, arg2, dbname):
print("Test")
return sqlite.SQLITE_OK #should allow all operations
conn = sqlite.connect(":memory:")
conn.execute("CREATE TABLE A (name integer PRIMARY KEY AUTOINCREMENT)")
conn.set_authorizer(select_authorizer)
conn.execute("SELECT * FROM A").fetchall() #should still work
This gives me a sqlite3.DatabaseError: not authorized, without ever printing out "Test". I'm guessing I may have set up my authorizer wrong, and it's just failing to even call it. (Though the error message sure doesn't communicate that) But according to the documentation, this setup looks right.
EDIT: Changed sqlite.SQLITE_OKAY to sqlite.SQLITE_OK, but since the method doesn't seem to be called at all, not surprisingly that didn't help.
The authorizer callback takes 5 arguments, but yours only accepts four:
The first argument to the callback signifies what kind of operation is to be authorized. The second and third argument will be arguments or None depending on the first argument. The 4th argument is the name of the database (“main”, “temp”, etc.) if applicable. The 5th argument is the name of the inner-most trigger or view that is responsible for the access attempt or None if this access attempt is directly from input SQL code.
Thus, the signature should be:
def select_authorizer(sqltype, arg1, arg2, dbname, source):
Generally, when testing a callback like that, testing is made easy by using a *args wildcard parameter:
def select_authorizer(*args):
print(args)
return sqlite.SQLITE_OK
The above callback prints out:
(21, None, None, None, None)
(20, 'A', 'name', 'main', None)
when I run your test SELECT.
See the C reference for SQLite set_authorizer and the action codes reference for the various constants used.
Martijn Pieter's answer is correct; I somehow missed that 5th argument when I read that paragraph.
Something I've also found reading through the documentation more closely that would have really helped me figure this out on my own is the line: sqlite.enable_callback_tracebacks(True)
This line will cause sqlite to print a traceback for errors that occur within callback functions.