Prisma queryRaw returning date as string - sql

Issue: When I use prisma.$queryRaw, it returns my date as a string, even though I specify the query's return type. If I use prisma.find then it returns it correctly. But, I have to use queryRaw because of the complexity of the query.
schema.prisma has the date defined like such:
effectiveDate DateTime? #map("effective_date") #db.Date
So, the model object has the field defined like effectiveDate: Date | null
The query looks something like this:
const catalogCourses: CatalogCourse[] = await prisma.$queryRaw<CatalogCourse[]>`
SELECT
id,
campus,
effective_date as "effectiveDate",
...rest of the query ommitted here because it's not important
If I then do something like
console.log(`typeof date: ${typeof catalogCourses[0].effectiveDate}, value ${catalogCourses[0].effectiveDate}`)
The result shows typeof date: string, value 2000-12-31. Why isn't it a date? I need to be able to work with it as a Date, but if I do effectiveDate.getTime() for example, it errors during runtime, saying 'getTime is not a function', which it is doc. If I try and do new Date(effectiveDate), that doesn't work either because typescript sees the field as a Date object already. EDIT: I was incorrect about why the previous statement wasn't working; doing new Date(effectiveDate) does work.
I do see in the prisma docs that it says:
Type caveats when using raw SQL When you type the results of
$queryRaw, the raw data does not always match the suggested TypeScript
type.
Is there a way for queryRaw to return my date as a Date object?

Related

Prevent Oracle error ORA-18043 in select statement

I'm storing in a table the logs of an API in my application. In one of the columns, I store the raw Json sent in the HTTP request.
I've been tasked to create a page in my application dedicated to easily explore every entered logs, with filters, sorting, etc.
One of the sorting needed is on the date that was indicated in the Json body of the HTTP call. I've managed to do so using the Oracle's Json API :
SELECT *
FROM FUNDING_REQUEST f
ORDER BY TO_TIMESTAMP_TZ(JSON_VALUE(
f.REQUEST_CONTENTS,
'$.leasing_information.consumer_request_date_time'
), 'YYYY/MM/DD"T"HH24:MI:SS.FFTZH:TZM') ASC
This works either if $.leasing_information.consumer_request_date_time is defined or not but I have an issue when the value is wrongly formatted. In one of my test, I sent this to my API :
{
[...],
"leasing_information": {
"consumer_request_date_time": "2021-25-09T12:30:00.000+02:00",
[...]
}
}
There is no 25th month, and my SQL query now returns the following error :
ORA-01843: not a valid month.
I would like to handle this value as NULL rather than returning an error, but it seems like the TO_TIMESTAMP_TZ DEFAULT clause does not really work the way I want it to. Doing this also returns an error :
SELECT *
FROM FUNDING_REQUEST f
ORDER BY TO_TIMESTAMP_TZ(JSON_VALUE(
f.REQUEST_CONTENTS,
'$.leasing_information.consumer_request_date_time'
) DEFAULT NULL ON CONVERSION ERROR, 'YYYY/MM/DD"T"HH24:MI:SS.FFTZH:TZM') ASC
ORA-00932:inconsistent datatypes ; expected : - ; got : TIMESTAMP WITH TIME ZONE
I would also like to avoid using a PL/SQL function if possible, how can I prevent this request from returning an error ?
You don't need to extract a string and then convert that to a timestamp; you can do that within the json_value(), and return null if that errors - at least from version 12c Release 2 onwards:
SELECT *
FROM FUNDING_REQUEST f
ORDER BY JSON_VALUE(
f.REQUEST_CONTENTS,
'$.leasing_information.consumer_request_date_time'
RETURNING TIMESTAMP WITH TIME ZONE
NULL ON ERROR
) ASC
db<>fiddle, including showing what the string and timestamp extractions evaluate too (i.e. a real timestamp value, or null).

How to use sql statement in django?

I want to get the latest date from my database.
Here is my sql statement.
select "RegDate"
from "Dev"
where "RegDate" = (
select max("RegDate") from "Dev")
It works in my database.
But how can I use it in django?
I tried these codes but it return error. These code are in views.py.
Version 1:
lastest_date = Dev.objects.filter(reg_date=max(reg_date))
Error:
'NoneType' object is not iterable
Version 2:
last_activation_date = Dev.objects.filter(regdate='reg_date').order_by('-regdate')[0]
Error:
"'reg_date' value has an invalid format. It must be in YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] format."
I've defined reg_date at beginning of the class.
What should I do for this?
You make things too complicated, you simply order by regdate, that's all:
last_activation_dev = Dev.objects.order_by('-regdate').first()
The .first() will return such Dev object if it is available, or None if there are no Dev objects.
If you only are interested in the regdate column itself, you can use .values_list(..):
last_activation_date = Dev.objects.order_by('-regdate').values_list('regdate', flat=True).first()
By using .filter() you actually were filtering the Dev table by Dev records such that the regdate column had as value 'reg_date', since 'reg_date' is not a valid datetime format, this thus produced an error.

ToDate function provides unexpected output

I used the ToDate(userinput, format) function to covert my chararray field. I used the ToDate(userinput, 'MM/dd/yyyy') to covert the field from chararray to date but looks like i am not seeing the output as i had expected.
Here is the code:
l_dat = load 'textfile' using PigStorage('|') as (first:chararray,last:chararray,dob:chararray);
c_dat = foreach l_dat generate ToDate(dob,'MM/dd/yyyy') as mydate;
describe c_dat;
dump c_dat;
data looks like this:
(firstname1,lastname1,02/02/1967)
(John,deloy,05/26/1967)
(frank,fun,05/18/1967)
Output looks like this:
c_dat: {mydate: datetime}
(1967-05-26T00:00:00.000-04:00)
(1967-05-18T00:00:00.000-04:00)
(1967-02-02T00:00:00.000-05:00)
The output i was expecting was dateObjects with data as shown below:
(05/26/1967)
(05/18/1967)
(02/02/1967)
Please advise if i am doing anything wrong?
Ref : http://pig.apache.org/docs/r0.12.0/func.html#to-date, the return type of ToDate function is DateTime object. You can observe that in the schema description shared in output
c_dat: {mydate: datetime}
If you are having the date in the required format, you need not do any conversion.
c_dat = foreach l_dat generate dob as mydate;
If you are interested in converting the chararray date to any other format then you have to use ToString() function after getting the DateTime object.
Step 1: Convert date chararray to Date Time Ojbect using ToDate(datesstring, inutformat)
Step 2 : Use ToString(DateTime object, required format) to get the string date in the required format.
This can be achieved in a single step as below.
ToString(ToDate(date,inputformat),requiredformat);
Ref : http://pig.apache.org/docs/r0.12.0/func.html#to-string for details.

Linq to sql - get value from db function and not directly from the db field (while mapping properties)

When you map a table to an object, every property created corresponds to one db column.
I want to execute a db function on a column before it gets mapped to the property, so the property gets the value returned by the db function, and not the column
I was trying to achieve that by Expression property of ColumnAttribute (as in the example below), so instead of BirthDate the usrFn_UTCToLocalTime(BirthDate) is returned
but it does not seem to be working and still gets pure value of the column.
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage = "_BirthDate", DbType = "DateTime", UpdateCheck = UpdateCheck.Never, Expression = "dbo.usrFn_UTCToLocalTime(BirthDate)")]
public System.Nullable<System.DateTime> BirthDate
{
get
{
return this._BirthDate;
}
}
I have also modified the DBML XML as in:
other post on stackoverflow
but also without result.
Is that possible by using LINQ or do I have to overwrite a getter which costs roundtrip to the server?
According to the Remarks section on this MSDN page, the Expression property of the ColumnAttribute is used when calling CreateDatabase, so it won't work the way you intend unless you created your database with Linq to Sql.
You can create a Linq query that selects the various columns and calls the db function in one statement like this (based on MSDN example):
var qry = from person in db.Persons
select new {
FirstName = person.FirstName,
LastName = person.LastName,
BirthDate = person.BirthDate,
Dob = db.usrFn_UTCToLocalTime(person.BirthDate)
};
This projects into an anonymous type, but you could use a non-anonymous type as well. For the sake of the example, I've got a table named Person with FirstName, LastName, and BirthDate columns, and a user defined scalar function named usrFn_UTCToLocalTime. The sql statement sent to the server is:
SELECT [t0].[FirstName], [t0].[LastName], [t0].[BirthDate], CONVERT(DateTime,[dbo].[usrFn_UTCToLocalTime]([t0].[BirthDate])) AS [Dob]
FROM [dbo].[Person] AS [t0]
As I was suggesting in the question, for now I have overwritten the get method so I have:
get
{
using (var context = DB.Data.DataContextFactory.CreateContext())
{
return context.usrFn_UTCToLocalTime(_BirthDate);
}
//return this._BirthDate;
}
But with every access to the property, roundtrip is made - which is not my intention but gives a proper result.
I leave the question still open

NHibernate Like with integer

I have a NHibernate search function where I receive integers and want to return results where at least the beginning coincides with the integers, e.g.
received integer: 729
returns: 729445, 7291 etc.
The database column is of type int, as is the property "Id" of Foo.
But
int id = 729;
var criteria = session.CreateCriteria(typeof(Foo))
criteria.Add(NHibernate.Criterion.Expression.InsensitiveLike("Id", id.ToString() + "%"));
return criteria.List<Foo>();
does result in an error (Could not convert parameter string to int32). Is there something wrong in the code, a work around, or other solution?
How about this:
int id = 729;
var criteria = session.CreateCriteria(typeof(Foo))
criteria.Add(Expression.Like(Projections.Cast(NHibernateUtil.String, Projections.Property("Id")), id.ToString(), MatchMode.Anywhere));
return criteria.List<Foo>();
Have you tried something like this:
int id = 729;
var criteria = session.CreateCriteria(typeof(Foo))
criteria.Add(NHibernate.Criterion.Expression.Like(Projections.SqlFunction("to_char", NHibernate.NHibernateUtil.String, Projections.Property("Id")), id.ToString() + "%"));
return criteria.List<Foo>();
The idea is convert the column before using a to_char function. Some databases do this automatically.
AFAIK, you'll need to store your integer as a string in the database if you want to use the built in NHibernate functionality for this (I would recommend this approach even without NHibernate - the minute you start doing 'like' searches you are dealing with a string, not a number - think US Zip Codes, etc...).
You could also do it mathematically in a database-specific function (or convert to a string as described in Thiago Azevedo's answer), but I imagine these options would be significantly slower, and also have potential to tie you to a specific database.