Rails - Heroku Postgresql SQL Error - Works on Local SQLite - Error "ActiveRecord:Invalid Relation" - postgresql

Hi here is my ActiveRelation query that works fine on local development environment (SQLite)
#table2_items = #table1var.table2_items.find(:all, conditions: ["status1 is ? AND status2 is ? AND start_datetime > ?", true, nil, Time.now.to_datetime], order: [:field_id, :created_at])
I think it's just a syntax error... Can anyone help? Thanks

Your SQL ends up with this in it:
status1 is 't'
and that's invalid: is is only used with is null, is distinct from, and similar constructs.
You should upgrade to a more modern syntax and leave most of the work to ActiveRecord:
#table2_items = #table1var.table2_items
.where(:status1 => true, :status2 => nil)
.where('start_datetime > ?', Time.now)
.order(:field_id, :created_at)
That leaves most of the "how do I compare things?" logic up ActiveRecord and is a bit easier to read as the placeholders and their values aren't separated from each other.
Once you have this problem sorted out, you really should install PostgreSQL in your development environment so that you're developing and deploying on the same stack. There are all sorts of differences between databases that no ORM can protect you from.

Related

Code running in Dbeaver but not working when I implement the same via dbt

I am new to this thing and I have a doubt. I am migrating flows from tableau prep to dbt. There is this filter that is used in prep which goes like
NOT ((([Tactic] == "Awareness") AND NOT (ISNULL([Tactic]))))
and my corresponding code is like : (tactic = 'Awareness' and tactic is not null) = false,
tactic is a calculated field where we are deriving the values of tactic from other fields.
This code runs perfectly fine when I am using my sql editor(dbeaver) but does not give me proper values when I run it in DBT Awareness is included in the dbt output.
Here are the versions :
DBT: 1.2.2
postgres: 1.2.2
redshift: 1.2.0
The packages cannot be upgraded as these will create issues in other flows that are being derived from my own flow.
has anyone else encountered a same issue or can someone please help me out with this?
I have tried doing tactic <> 'Awareness'.
There is a subtle bug here related to null handling that could be causing this.
For null values, tactic = 'Awareness' will be null, and null and true will also be null, which is not equal to false.
Generally, comparisons to booleans in Redshift should use is false, not = false, and in this case, you really want not ... is true, not is false, since not (null is true) is true, but null is false is false.
I'd refactor this whole thing to something less dependent on the specifics of null handling for boolean operators for your database:
coalesce(tactic, '') <> 'Awareness'

What is the difference between `ARRAY[(value'::text]` and `ARRAY['value']::text[]`

This shows up in our schema.rb diff sometimes, and I asked my team around and it seems they all have the same postgresql version. With a conditional index, the dumped schema sometimes look like this:
t.index ["field_name"], name: "irrelevant", unique: true,
where: "((state))::text = ANY (ARRAY[('applied'::character varying)::text]))"
and sometimes like that:
t.index ["field_name"], name: "irrelevant", unique: true,
where: "((state))::text = ANY (ARRAY['applied'::character varying]::text[]))"
so the difference seems to be only with the way the casting is expressed:
ARRAY['string'::text]
// vs
ARRAY['string']::text[]
It seems to me those two castings are equivalent. So my first question is: Are they?
And my second question: where is this discrepancy coming from? As mentioned before all my teammates seem to have the same PGSQL version (though there might be a few missing data points). They definitely have the same rails version, so that can't be the source.
The two syntax variants have the same meaning, and PostgreSQL treats them the same. The difference you observe is not caused by a version difference in PostgreSQL, but perhaps in Ruby on Rails.

Clojure JDBC - This ResultSet is closed

I am currently learning using Clojure and connection with postgresql and I am stuck. In my code, I can successfully query using SELECT using java.jdbc dependency but got an exception when I UPDATE or INSERT
I am using these dependencies
[org.clojure/java.jdbc "0.7.8"]
[postgresql "9.3-1102.jdbc41"]
This is my working code for SELECT-ing from a table called public."user"
(ns knp-api.model.user
(:require [clojure.java.jdbc :as sql]))
(def db "jdbc:postgresql://ampersanda#localhost:5432/idjoesoft_klinik")
(defn get-count [q]
"Get count key from query
It takes jdbc.query as parameter"
(:count (first (into [] q))))
(defn is-user-email-available? [e]
"Returns boolean when email is available.
Take one parameter, it's email"
(let [q "SELECT COUNT(*) FROM public.\"user\" t WHERE user_email = ?"]
(sql/query db [q e] {:result-set-fn #(= 1 (get-count %))})))
and this is not my code which makes an exception appear
(defn set-user-timestamp-and-token [email token timestamp]
"update user current token and last login time inside database.
Takes email, token, and current timestamp as parameter"
(sql/update! db
"public.\"user\""
{:user_last_login (str "to_timestamp(" timestamp ")")
:user_token token}
["user_email = ?" email]))
and this is the exception
UPDATE
I also try using REPL to create table and I also get the same results.
knp-api.handler=> (require '[clojure.java.jdbc :as sql])
nil
knp-api.handler=> (sql/db-do-commands "jdbc:postgresql://ampersanda#localhost:5432/idjoesoft_klinik" (sql/create-table-ddl :testing [[:data :text]]))
PSQLException This ResultSet is closed. org.postgresql.jdbc2.AbstractJdbc2ResultSet.checkClosed (AbstractJdbc2ResultSet.java:2852)
I suspect the update is happening fine, and then it's trying to return the rows that changed, and it's trying to do so as a lazy sequence. the thing that tries to print/process that lazy sequence of results may be doing so after the connection is closed.
try wrapping the select statement in a call to doall to ensure that it's read immediately and not allowed to be a lazy database.
Having run into the same issue today, the root cause is the postgresql java driver.
postgresql "9.3-1102.jdbc41" is five years old, after upgrading to 42.2.6 the issue went away.
I remember having this problem, but it's many years ago and I can't remember the solution. However, wrapping raw JDBC in Clojure is not a good idea. There are a number of excellent Clojure libraries which make working with databases much easier. I'd particularly recomment SQL Korma and Hug SQL.
Having spent a while trying to get this solved I can confirm in my case updating the postgresql java driver solved this issue, if anybody is having the same issue try to use the newest driver from clojars/maven, Clojars even has a message telling you that you should use the version from maven central.

Performance issue with fluent query in EF vs SharpRepository

I was having some performance issues using SharpRepository, and after playing around the SQL Query Profiler I found the reason.
With EF I can do stuff like this:
var books = db.Books.Where(item => item.Year == '2016');
if (!string.IsNullorEmpty(search_author))
books = books.Where(item => item.Author.Contains(search_author);
return (books.ToList());
EF will not really do anything until books is used (last line) and then it will compile a query that will select only the small set of data matching year and author from the db.
But SharpRepository evaluates books at once, so this:
var books = book_repo.Books.FindAll(item => item.Year == '2016');
if (!string.IsNullorEmpty(search_author))
books = books.Where(item => item.Author.Contains(search_author);
return (books.ToList());
will compile a query like "select * from Books where Year == '2016'" at the first line, and get ALL those records from the database! Then at the second line it will make a search for the author within the C# code... That behaviour can be a major difference in performance when using large databases, and it explains why my queries timed out...
I tried using repo.GetAll().Where() instead of repo.FindAll().... but it worked the same way.
Am I misunderstanding something here, and is there a way around this issue?
You can use repo.AsQueryable() but by doing that you lose some of the functionality that SharpRepository can provide, like caching or and aspects/hooks you are using. It basically takes you out of the generic repo layer and lets you use the underlying LINQ provider. It has it's benefits for sure but in your case you can just build the Predicate conditionally and pass that in to the FindAll method.
You can do this by building an Expression predicate or using Specifications. Working with the Linq expressions does not always feel clean, but you can do it. Or you can use the Specification pattern built into SharpRepository.
ISpecification<Book> spec = new Specification<Book>(x => x.Year == 2016);
if (!string.IsNullorEmpty(search_author))
{
spec = spec.And(x => x.Author.Contains(search_author));
}
return repo.FindAll(spec);
For more info on Specifications you can look here: https://github.com/SharpRepository/SharpRepository/blob/develop/SharpRepository.Samples/HowToUseSpecifications.cs
Ivan Stoev provided this answer:
"The problem is that most of the repository methods return IEnumerable. Try repo.AsQueryable(). "

Aqua Data studio won't let me create this view

I'm running a Postgres Database on Aqua Data Studio 6.5.12 (Yes, it is a really old system, but i like it very much :) ).
I've got a query running normally in the Query Analyzer, but when I try to save it as a view, I'm receiving "ERROR: Syntax error near SELECT".
Do someone know what could be wrong in it?
SELECT test_configs.sgsn, test_configs.imsi,
CASE test_configs.mncl
WHEN '' THEN '-'
ELSE COALESCE(test_configs.mncl, '-')
END AS mncl
FROM config_imsis_sgsn AS default_configs
LEFT JOIN config_imsis_sgsn AS test_configs
ON default_configs.sgsn = f_sgsn_correto()
AND default_configs.imsi = test_configs.imsi
AND test_configs.sgsn <> default_configs.sgsn
WHERE COALESCE(default_configs.mncl, 'null') <> COALESCE(test_configs.mncl, 'null') AND test_configs.sgsn <> ''
Thank you!
The CASE statement is malformed.
Try modifying the SELECT to be like this:
SELECT test_configs.sgsn, test_configs.imsi,
CASE
WHEN test_configs.mncl = '' THEN '-'
ELSE COALESCE(test_configs.mncl, '-')
END AS mncl
Note that I am basing this behavior off of Postgres 9.3, although I don't think this particular behavior has changed in quite some time. I assume that your version of Postgres that Aqua Data Studio 6 is using is quite old, as, while I'm not familiar with that product, it would appear the most recent version is 14, indicating that it's likely many years old.