query optimisation in sqlalchemy - sqlalchemy

How to select object by id, then get email from that object and filter all objects by this email sqlalchemy
obj = db.session.query(SomeModel).filter_by(id=some_id).first()
email = obj.email
db.session.query(SomeModel).filter_by(email=email)
How to do that in one query in SQLAlchemy

Something like this ought to work (untested). You create a subquery that filters on id and the main query can be filtered on the subquery result.
subquery = session.query(SomeModel).filter(SomeModel.id == some_id).subquery()
query = session.query(SomeModel).filter(SomeModel.email == subquery.c.email)

Related

SQLAlchemy build filter condition based on user inputs

In sqlalchemy, how to build filter condition based on user selections? This is what I tried, but doesn't seem to work
conditions =[]
if input.userid:
conditions.append( userdata.uid == input.userid)
if input.location:
conditions.append( userdata.location.like(f"{input.location}%") )
if input.username:
conditions.append( userdata.username.like(f"%{input.username}%") )
So based on user inputs, there may be 1, 2 or 3 filter conditions in the and_ operator. Below is my query
records = session.query(userdata).filter(and_(conditions)).all()
Or is it better to use from sqlalchemy.sql import text and generate a normal SQL query?
I like to do it like this-
query = session.query(userdata)
if input.userid:
query = query.filter(userdata.uid==input.userid)
if input.location:
query = query.filter(userdata.location.like(f"{input.location}%"))
records = query.all()

How to access columns of subqueries with jooq?

i am having troubles understanding how to access columns from a subquery (MySQL). Here is my code:
Personne personne = Personne.PERSONNE.as("personne");
Evenement evenement = Evenement.EVENEMENT.as("evenement");
Genealogie genealogie = Genealogie.GENEALOGIE.as("genealogie");
Lieu lieu = Lieu.LIEU.as("lieu");
SelectField<?>[] select = { DSL.countDistinct(personne.ID).as("countRs"), lieu.LIBELLE.as("libelleRs"),
lieu.ID.as("idVille") };
Table<?> fromPersonne = evenement.innerJoin(personne).on(personne.ID.eq(evenement.IDPERS))
.innerJoin(genealogie).on(genealogie.ID.eq(personne.IDGEN)).innerJoin(lieu)
.on(lieu.ID.eq(evenement.IDLIEU));
Table<?> fromFamille = evenement.innerJoin(personne).on(personne.IDFAM.eq(evenement.IDFAM))
.innerJoin(genealogie).on(genealogie.ID.eq(personne.IDGEN)).innerJoin(lieu)
.on(lieu.ID.eq(evenement.IDLIEU));
GroupField[] groupBy = { lieu.ID };
Condition condition = //conditionally build, not relevant i think
result = create.select(DSL.asterisk())
.from(create.select(select).from(fromPersonne).where(condition).groupBy(groupBy)
.union(create.select(select).from(fromFamille).where(condition).groupBy(groupBy)))
// i would like something like this but i don't know how: .groupBy(groupBy).fetch();
Basicly what i have is:
SELECT
*
FROM(
(SELECT
countRs, libelleRs, idVille
FROM
fromPersonne
WHERE
-- conditions
GROUP BY lieu.ID)
UNION
(SELECT
countRs, libelleRs, idVille
FROM
fromFamille
WHERE
-- conditions
GROUP BY lieu.ID)
)GROUP BY lieu.ID -- this is where i need help
In a plain MySQL query i would just give an alias to the union and then make a reference to the column i want to group by using the alias but it seems like it does not work like this with JOOQ.
I just need to group the results of the subqueries together but i don't know how to make a reference to the subqueries columns... I am sure i would have to reference my subqueries in objects outside of that "main select" to be able to access the columns or something along those lines but i am lost in all the object types.
You have to assign your derived table to a local variable and dereference columns from it, e.g.
Table<?> t = table(
select(...).from(...).groupBy(...).unionAll(select(...).from(...).groupBy(...))
).as("t");
Field<Integer> tId = t.field(lieu.ID);

How to make where condition always be true with field =?

I have a sql statement follow:
select * from table where id = ?
Now, problem is, l don't know whether front end will send me the value of id, if it did, this sql seem like id = 1, and if not, sql should be like id = true(fake code) to find all data
How could I write my sql?
Or, It is fundamentally wrong?
This is normally handled by using logic such as this:
select *
from table
where id = ? or ? is null;
If you don't want to pass the parameter twice or use named parameters:
select t.*
from table t cross join
(select ? as param) params
where id = params.param or params.param is null;
If you want to return all ids if the passed-in value does not exist:
select t.*
from table t
where id = ? or
not exists (select 1 from table t2 where t2.id = ?);
What you can try doing is in your code, write a function for fetching a specific record, and another function for fetching all the records from your table.
In PHP, it could be something like:
// Fetching a specific record
function getCustomerRecord($customerId) {
// Code to fetch specific record from database
}
// Fetching all records
function getAllCustomerRecords() {
// Code to fetch all records from database
}
In the function where you process requests received, check first if a value for id was passed. If a value for id was passed, call the function to fetch a specific record, making sure to pass along the value you received as an argument. Otherwise, call the function to fetch all the records from your table.
You can try doing this to get your right sql statement in PHP
function GetSqlStatement($id){
return $sql = "select * from table where id = ".$id.";";
}

Dynamically passing of parameter in rails sql query

Below is an SQL query which fetches some data related to user.
def self.get_user_details(user_id)
result = Event.execute_sql("select replace(substring_index(properties, 'text', -1),'}','') as p, count(*) as count
from ahoy_events e where e.user_id = ?
group by p order by count desc limit 5", :user_id)
return result
end
I want to dynamically pass values to user id to get the result.
I am using the below method to sanitize sql array, but still it returns no result. The query works fine if given static parameter.
def self.execute_sql(*sql_array)
connection.execute(send(:sanitize_sql_array, sql_array))
end
Because the query is complicated I am couldn't figure out the ActiveRecord way to get the results.
Is there any way I could get this sorted out?
I don't know why that should not work. May SQL-Syntac SELECT * FROM users ...
dynamic passing some other way you can do this: "some string #{user.id#ruby code} some more string"
You can do querys in Activerecord like this: User.where(id: user.id).where(field2: value2).group_by(:somevalue).order(:id)

Check if query result is empty

I am performing a query to a database in ruby using Sequel ORM. The query is performed by:
query = "SELECT * FROM albums WHERE artist = 'John';"
DB.fetch(query)
I would like to check whether the result of the query is empty, i.e. if not entry of the DB matches the query conditions.
I could:
empty = true
DB.fetch(query) do |row|
empty = false
end
but I would like to know whether there is a direct method to chek whether the query returns no result.
You want the empty? method:
query = "SELECT * FROM albums WHERE artist = 'John';"
empty = DB.fetch(query).empty?