Dynamic variable parameter in static mysql query using groovy soap ui - groovy

I would like to generate the query that results for the BeneficiaryID 'ABC123' along with some other inputs if they were also given. Suppose if the currency value is given, I would like to include the Currency condition as well in the JOIN query, so as well the Category. I have the following code snippet in the SOAP UI Groovy script.
query= " CORR.BeneficiaryID LIKE 'ABC123'"
if (currencyValue!=""){
query=query + " and CORR.Currency LIKE '${currencyValue}'"
}
if (CategoryValue!=""){
query=query + " and CORR.Category LIKE '${CategoryValue}'"
}
log.info("Query" + query)
Outputrows = sql.rows("select CORR.Preferred as preferred ,CORR.Category as category,CORR.Currency as currency\
from BENEFICIARY CORR \
JOIN LOCATION LOC on CORR.UID=LOC.UID and ${query}
log.info("Output rows size" + Outputrows.size())
When currency and category are not given, I would like to have the following query run and get me the results.
select CORR.Preferred as preferred ,CORR.Category as category,CORR.Currency as currency\
from BENEFICIARY CORR \
JOIN LOCATION LOC on CORR.UID=LOC.UID and CORR.BeneficiaryID LIKE 'ABC123'
and when the currency and category are given(say USD & Commercial), then the following query.
select CORR.Preferred as preferred ,CORR.Category as category,CORR.Currency as currency\
from BENEFICIARY CORR \
JOIN LOCATION LOC on CORR.UID=LOC.UID and CORR.BeneficiaryID LIKE 'ABC123' and CORR.Currency LIKE 'USD' and CORR.Category LIKE 'Commercial'
All I could see on the result for Outputrows.size() is zero(0).
Can you please correct me where am I doing wrong.
Thanks.

Here is changed script.
Since the issue to just build query, only putting that part remove sql execution part as that is not really the issue.
//Define the values or remove if you get those value from somewhere else
//Just put them here to demonstrate
//You may also try by empty value to make sure you are getting the right query
def currencyValue = 'USD'
def categoryValue = 'Commercial'
def query = 'select CORR.Preferred as preferred, CORR.Category as category,CORR.Currency as currency from BENEFICIARY CORR JOIN LOCATION LOC on CORR.UID = LOC.UID and CORR.BeneficiaryID LIKE \'ABC123\''
currencyValue ? (query += " and CORR.Currency LIKE '${currencyValue}'") : query
categoryValue ? (query += " and CORR.Category LIKE '${categoryValue}'") : query
log.info "Final query is \n ${query}"
You can just pass query to further where you need to run the sql, say sql.rows(query)
You may quickly try Demo

Related

How to log parameters instead of placeholders using sqlx with Postgres?

I'm using sqlx for the first time today.
I'm having really hard time understanding my SQL errors because I cannot copy & paste logged queries in my IDE because the parameters are not converted from placeholders.
It prints:
SELECT * from players where team_id = $1 AND id = $2
but I would like the below instead:
SELECT * from players where team_id = 'ABC' AND id = '123'
How to do this?

How to apply DISTINCT on only date part of datetime field in sqlalchemy python?

I need to query my database and return the result by applying Distinct on only date part of datetime field.
My code is:
#blueprint.route('/<field_id>/timeline', methods=['GET'])
#blueprint.response(field_timeline_paged_schema)
def get_field_timeline(
field_id,
page=1,
size=10,
order_by=['capture_datetime desc'],
**kwargs
):
session = flask.g.session
field = fetch_field(session, parse_uuid(field_id))
if field:
query = session.query(
func.distinct(cast(Capture.capture_datetime, Date)),
Capture.capture_datetime.label('event_date'),
Capture.tags['visibility'].label('visibility')
).filter(Capture.field_id == parse_uuid(field_id))
return paginate(
query=query,
order_by=order_by,
page=page,
size=size
)
However this returns the following error:
(psycopg2.errors.InvalidColumnReference) for SELECT DISTINCT, ORDER BY expressions must appear in select list
The resulting query is:
SELECT distinct(CAST(tenant_resson.capture.capture_datetime AS DATE)) AS distinct_1, CAST(tenant_resson.capture.capture_datetime AS DATE) AS event_date, tenant_resson.capture.tags -> %(tags_1)s AS visibility
FROM tenant_resson.capture
WHERE tenant_resson.capture.field_id = %(field_id_1)s
Error is:
Query error - {'error': ProgrammingError('(psycopg2.errors.InvalidColumnReference) SELECT DISTINCT ON expressions must match initial ORDER BY expressions\nLINE 2: FROM (SELECT DISTINCT ON (CAST(tenant_resson.capture.capture...\n ^\n',)
How to resolve this issue? Cast is not working for order_by.
I am not familiar with sqlalchemy but this resulting query works as you expect. Please note the DISTINCT ON.
Maybe there is a way in sqlalchemy to execute non-trivial parameterized queries? This would give you the extra benefit to be able to test and optimize the query upfront.
SELECT DISTINCT ON (CAST(tenant_resson.capture.capture_datetime AS DATE))
CAST(tenant_resson.capture.capture_datetime AS DATE) AS event_date,
tenant_resson.capture.tags -> %(tags_1)s AS visibility
FROM tenant_resson.capture
WHERE tenant_resson.capture.field_id = %(field_id_1)s;
You can order by event_date if your business logic needs.
The query posted by #Stefanov.sm is correct. In SQLAlchemy terms it would be
query = (
session.query(
Capture.capture_datetime.label('event_date'),
Capture.tags['visibility'].label('visibility')
).distinct(cast(Capture.capture_datetime, Date))\
.filter(Capture.field_id == parse_uuid(field_id))
)
See the docs for more information
I needed to add order_by to my query. Now it works fine.
query = session.query(
cast(Capture.capture_datetime, Date).label('event_date'),
Capture.tags['visibility'].label('visibility')
).filter(Capture.field_id == parse_uuid(field_id)) \
.distinct(cast(Capture.capture_datetime, Date)) \
.order_by(cast(Capture.capture_datetime, Date).desc())

Need help fetching data from a column

Sorry for this but I'm real new to sqlite: i've created a database from an excel sheet I had, and I can't seem to fetch the values of the column I need
query = """ SELECT GNCR from table"""
cur.execute(query)
This actually works, but
query = """ SELECT ? from table"""
cur.execute(query, my_tuple)
doesn't
Here's my code:
def print_col(to_print):
db = sqlite3.connect('my_database.db')
cur = db.cursor()
query = " SELECT ? FROM my_table "
cur.execute(query, to_print)
results = cur.fetchall()
print(results)
print_col(('GNCR',))
The result is:
[('GNCR',), ('GNCR',), ('GNCR',), ('GNCR',), [...]]
instead of the actual values
What's the problem ? I can't figure it out
the "?" character in query is used for parameter substitution. Sqlite will escape the parameter you passed and replace "?" with the send text. So in effect you query after parameter substitution will be SELECT 'GNCR' FROM my_table where GNCR will be treated as text so you will get the text for each row returned by you query instead of the value of that column.
Basically you should use the query parameter where you want to substitute the parameter with escaped string like in where clause. You can't use it for column name.

Python/Peewee query with fn.MAX and alias results in "no such attribute"

I have a peewee query that looks like this:
toptx24h = Transaction.select(fn.MAX(Transaction.amount).alias('amount'), User.user_name).join(User,on=(User.wallet_address==Transaction.source_address)).where(Transaction.created > past_dt).limit(1)
My understanding is this should be equivalent to:
select MAX(t.amount) as amount, u.user_name from transaction t inner join user u on u.wallet_address = t.source_address where transaction.created > past_dt limit 1
My question is how to I access the results user_name and amount
When I try this, I get an error saying top has no attribute named amount
for top in toptx24h:
top.amount # No such attribute amount
I'm just wondering how i can access the amount and user_name from the select query.
Thanks
I think you need a GROUP BY clause to ensure you're grouping by User.username.
I wrote some test code and confirmed it's working:
with self.database.atomic():
charlie = TUser.create(username='charlie')
huey = TUser.create(username='huey')
data = (
(charlie, 10.),
(charlie, 20.),
(charlie, 30.),
(huey, 1.5),
(huey, 2.5))
for user, amount in data:
Transaction.create(user=user, amount=amount)
amount = fn.MAX(Transaction.amount).alias('amount')
query = (Transaction
.select(amount, TUser.username)
.join(TUser)
.group_by(TUser.username)
.order_by(TUser.username))
with self.assertQueryCount(1):
data = [(txn.amount, txn.user.username) for txn in query]
self.assertEqual(data, [
(30., 'charlie'),
(2.5, 'huey')])

Subsonic 3 Simple Query inner join sql syntax

I want to perform a simple join on two tables (BusinessUnit and UserBusinessUnit), so I can get a list of all BusinessUnits allocated to a given user.
The first attempt works, but there's no override of Select which allows me to restrict the columns returned (I get all columns from both tables):
var db = new KensDB();
SqlQuery query = db.Select
.From<BusinessUnit>()
.InnerJoin<UserBusinessUnit>( BusinessUnitTable.IdColumn, UserBusinessUnitTable.BusinessUnitIdColumn )
.Where( BusinessUnitTable.RecordStatusColumn ).IsEqualTo( 1 )
.And( UserBusinessUnitTable.UserIdColumn ).IsEqualTo( userId );
The second attept allows the column name restriction, but the generated sql contains pluralised table names (?)
SqlQuery query = new Select( new string[] { BusinessUnitTable.IdColumn, BusinessUnitTable.NameColumn } )
.From<BusinessUnit>()
.InnerJoin<UserBusinessUnit>( BusinessUnitTable.IdColumn, UserBusinessUnitTable.BusinessUnitIdColumn )
.Where( BusinessUnitTable.RecordStatusColumn ).IsEqualTo( 1 )
.And( UserBusinessUnitTable.UserIdColumn ).IsEqualTo( userId );
Produces...
SELECT [BusinessUnits].[Id], [BusinessUnits].[Name]
FROM [BusinessUnits]
INNER JOIN [UserBusinessUnits]
ON [BusinessUnits].[Id] = [UserBusinessUnits].[BusinessUnitId]
WHERE [BusinessUnits].[RecordStatus] = #0
AND [UserBusinessUnits].[UserId] = #1
So, two questions:
- How do I restrict the columns returned in method 1?
- Why does method 2 pluralise the column names in the generated SQL (and can I get round this?)
I'm using 3.0.0.3...
So far my experience with 3.0.0.3 suggests that this is not possible yet with the query tool, although it is with version 2.
I think the preferred method (so far) with version 3 is to use a linq query with something like:
var busUnits = from b in BusinessUnit.All()
join u in UserBusinessUnit.All() on b.Id equals u.BusinessUnitId
select b;
I ran into the pluralized table names myself, but it was because I'd only re-run one template after making schema changes.
Once I re-ran all the templates, the plural table names went away.
Try re-running all 4 templates and see if that solves it for you.

Resources