Peewee update a field to the result of a function - postgresql

I have a function that takes one database field and modifies it so it can become another field.
I'm trying to run this:
def get_text_words(text):
if not text:
return []
else:
# Return a list of words that make up text
return text.split(' ')
q = Text.update(Text.words = get_text_words(Text.text))
q.execute()
When I run it, it returns an empty list. After some investigation with print statements, the function get_text_words is receiving a peewee <TextField> object rather than the text value of the field. It's not passing the if text: statement and returning an empty list as a result.
I know that I could iterate, calculate, and save, but I'd like to see if there's a possibility of running it in one query like the above so it's fast. I've already blanked out the database (no worries, it's a duplicate of production), so the query ran, just not sure how to operate on the value of the field.
Is there a way to run that type of update statement where it takes one field and puts it through a function that operates on the value and returns the result to assign to another field?

You don't seem to realize that the update() method results in the generation of a SQL UPDATE query. The only way your code would work is if, somehow, Peewee decompiled the Python and translated it into SQL.
You want to apply a SQL function, so look in your database for the function...Seems like you want Postgres string_to_array since you're trying to get a list?
So:
q = Text.update({Text.words: fn.string_to_array(Text.text, ' ')})

Related

SSRS multi value parameter - can't get it to work

First off this is my first attempt at a multi select. I've done a lot of searching but I can't find the answer that works for me.
I have a postgresql query which has bg.revision_key in (_revision_key) which holds the parameter. A side note, we've named all our parameters in the queries with the underscore and they all work, they are single select in SSRS.
In my SSRS report I have a parameter called Revision Key Segment which is the multi select parameter. I've ticked Allow multi value and in Available Values I have value field pointing to revision_key in the dataset.
In my dataset parameter options I have Parameter Value [#revision_key]
In my shared dataset I also have my parameter set to Allow multi value.
For some reason I can't seem to get the multi select to work so I must be missing something somewhere but I've ran out of ideas.
Unlike with SQL Server, when you connect to a database using an ODBC connection, the parameter support is different. You cannot use named parameters and instead have to use the ? syntax.
In order to accommodate multiple values you can concatenate them into a single string and use a like statement to search them. However, this is inefficient. Another approach is to use a function to split the values into an in-line table.
In PostgreSQL you can use an expression like this:
inner join (select CAST(regexp_split_to_table(?, ',') AS int) as filter) as my on my.filter = key_column
Then in the dataset properties, under the parameters tab, use an expression like this to concatenate the values:
=Join(Parameters!Keys.Value, ",")
In other words, the report is concatenating the values into a comma-separated list. The database is splitting them into a table of integers then inner joining on the values.

Convert varchar parameter with CSV into column values postgres

I have a postgres query with one input parameter of type varchar.
value of that parameter is used in where clause.
Till now only single value was sent to query but now we need to send multiple values such that they can be used with IN clause.
Earlier
value='abc'.
where data=value.//current usage
now
value='abc,def,ghk'.
where data in (value)//intended usage
I tried many ways i.e. providing value as
value='abc','def','ghk'
Or
value="abc","def","ghk" etc.
But none is working and query is not returning any result though there are some matching data available. If I provide the values directly in IN clause, I am seeing the data.
I think I should somehow split the parameter which is comma separated string into multiple values, but I am not sure how I can do that.
Please note its Postgres DB.
You can try to split input string into an array. Something like that:
where data = ANY(string_to_array('abc,def,ghk',','))

PHP and sanitizing strings for use in dynamicly created DB2 queries

I'm relatively new to DB2 for IBMi and am wondering the methods of how to properly cleanse data for a dynamically generated query in PHP.
For example if writing a PHP class which handles all database interactions one would have to pass table names and such, some of which cannot be passed in using db2_bind_param(). Does db2_prepare() cleanse the structured query on its own? Or is it possible a malformed query can be "executed" within a db2_prepare() call? I know there is db2_execute() but the db is doing something in db2_prepare() and I'm not sure what (just syntax validation?).
I know if the passed values are in no way effected by the result of user input there shouldn't be much of an issue, but if one wanted to cleanse data before using it in a query (without using db2_prepare()/db2_execute()) what is the checklist for db2? The only thing I can find is to escape single quotes by prefixing them with another single quote. Is that really all there is to watch out for?
There is no magic "cleansing" happening when you call db2_prepare() -- it will simply attempt to compile the string you pass as a single SQL statement. If it is not a valid DB2 SQL statement, the error will be returned. Same with db2_exec(), only it will do in one call what db2_prepare() and db2_execute() do separately.
EDIT (to address further questions from the OP).
Execution of every SQL statement has three stages:
Compilation (or preparation), when the statement is parsed, syntactically and semantically analyzed, the user's privileges are determined, and the statement execution plan is created.
Parameter binding -- an optional step that is only necessary when the statement contains parameter markers. At this stage each parameter data type is verified to match what the statement text expects based on the preparation.
Execution proper, when the query plan generated at step 1 is performed by the database engine, optionally using the parameter (variable) values provided at step 2. The statement results, if any, are then returned to the client.
db2_prepare(), db2_bind_param(), and db2_execute() correspond to steps 1, 2 and 3 respectively. db2_exec() combines steps 1 and 3, skipping step 2 and assuming the absence of parameter markers.
Now, speaking about parameter safety, the binding step ensures that the supplied parameter values correspond to the expected data type constraints. For example, in the query containing something like ...WHERE MyIntCol = ?, if I attempt to bind a character value to that parameter it will generate an error.
If instead I were to use db2_exec() and compose a statement like so:
$stmt = "SELECT * FROM MyTab WHERE MyIntCol=" . $parm
I could easily pass something like "0 or 1=1" as the value of $parm, which would produce a perfectly valid SQL statement that only then will be successfully parsed, prepared and executed by db2_exec().

Convert a Navision Filter to SQL where

I have a field in table in next format 1_2..1_10|1_6|1_8| where 1_2..1_10 include 1_2, 1_3 and other.
How I can select data, where number = 1_3?
1st suggestion: Get rights to modify the db structure and figure out how to better store the Navision string.
2nd suggestion: CLR
I'll assume you are relatively comfortable with each of these concepts. If you aren't they are very well documented all over the web.
My approach would be to use a CLR function as there's going to be some high level things that are awkward in SQL that C# takes care of quite easily. The psuedo walk through would go something like this.
Implementation
Create a CLR funciton and implement it on the SQL server instance.
Using SQL resultset change the query to look for the returned value of the CLR function based on the navision filter value where "1_3".
CLR Function Logic
Create a c# function that takes in the value of the filter field and returns a string value.
The CLR function splits the filter field by the | char into a list.
Inside the CLR function create a second list. Iterate over the first list. When you find a ranged string split it on the ".." and manually add every available value between the range to the second list. When you find a value that isnt' ranged simply add it to the second list.
Join the contents of the second list together on the "|" charecter.
Return the joined value.
SQL Logic
SELECT Field1,Field2...CLRFunctionName(FilterValue) AS FixedFilterValue FROM Sometable WHERE FixedFilterValue LIKE '%1_3%';

SELECT query in PostgreSQL

I am trying to retrieve values from a PostgreSQL database in a variable using a WHERE clause, but I am getting an error.
The query is:
select age into x from employee where name=name.GetValue()
name is the textcontrol in which I am entering a value from wxpython GUI.
I am getting an error as name schema doesn't exist.
What is the correct method for retrieving values?
"name.GetValue()" is a literal string, you are sending that to your db which knows nothing about wxpython and nothing about the variables in your program. You need to send the value of that data to your db, probably using bound parameters. Something like:
cur.execute("select age from employee where name=%s", [name.GetValue()])
x = cur.fetchone()[0] # returns a row containing [age] from the db
is probably what you're after. This will create a query with a placeholder in the database, then bind the value of name.GetValue() to that placeholder and execute the query. The next line fetches the first row of the result of the query and assigns x to the first item in that row.
I'm not positive what you are trying to do, but I think your issue might be syntax (misuse of INTO instead of AS):
SELECT age AS x FROM employee WHERE name = ....