Request columns for multiple tables using supabasejs - javascript

So supabase allows for two tables pretty simply.
const { data, error } = await supabase
.from('table1')
.select('table1.thing1, table1.thing2, table2(table2.thing2, table2.thing3)')
.console.log(data)
What I am trying to do is access a 3rd table to get information from table2 but I need table 1 to have the data.
const { data, error } = await supabase
.from('table1')
.select('table1.thing1, table2.thing2, table2(table2.thing2, table2.thing3), table3(table3.thing2, table3.thing2)')
console.log(data)
I would expect this to give me a data across all 3 but I just get a null returned.

With #supabase if you want to connect more than one table via supabasejs query your best bet is to just make a view. I hope this helps someone else out there!

Related

JSON GTFS TIMETABLE

What i want to do is get timetable from GTFS for specific bus. (Specific lane number) by node-gtfs.
My code looks like this:
const config = JSON.parse(
await readFile(new URL("./config.json", import.meta.url))
);
import { importGtfs } from "gtfs";
import { readFile, writeFile } from "fs/promises";
import { openDb } from "gtfs";
const db = await openDb(config);
try {
await importGtfs(config);
} catch (error) {
console.error(error);
}
import { getStoptimes } from "gtfs";
// Get all stoptimes
const trips = await getStoptimes();
//fs write file trips.json
await writeFile(
new URL("./trips.json", import.meta.url),
JSON.stringify(trips)
);
I'm trying to get just the timetable for specific bus lane, but i'm reciving some garbage and not even ONE timetable, i'm almost sure that i need to use more than one of those functions. No idea which, and how. (I also want to store it to the JSON File)
Also I was looking for some GTFS "tutorials" how to use it, how can i fetch data using node-gtfs but there is a really really small amount of them, almost none.
I've tried https://gtfstohtml.com/
It returns table for every BUS Lane in the HTML Table.
That is something similar that i want to do, add to that expandable list with the full timetable:
https://transit-arrivals-widget.blinktag.com/?stop_id=40585
Thanks !

Filtering in join in supabase

Im using supabase with a database which have 2 tables (that are implicates in this issue).
Tables are teachers and users. Both have ID and id_teacher/id_user respectively.
Im working in a query where i need to get all teacher, joining in users table, where theres a image column.
I need just to get the teachers where the user have an not null image.
const query = supabase.from(`teachers`).select(
`
*,
id_user(
image
)
`
)
This query works to get teachers joining in users table. Because i get my wanted response.
This is a short example.
{
"id": 560,
"teacher_experience": 9,
"id_user":{
"image": "example-image.jpg"
}
}
The trouble is when i try to use some filter to avoid null images.
query.not('id_user.image', 'eq', null)
query.not('id_user.image', 'in', null)
query.ilike('id_user.image', 'null')
Are just an examples o filters tha i tryed for avoid the teachers which user.image have a null value.
Because, i want to NOT GET the entire item, but i get an item wiht a id_user = null
{
"id": 560,
"teacher_experience": 9,
"id_user": null // In this case image is null but still giving me the user
}
How is the correct form to solve this?
Just create a view in database for solve this problem. A view is a shortcut to queries and it possible apply where clause.
In sql editor on supabase https://app.supabase.io/project/{your_project_id}/editor/sql
create a new view with joins;
CREATE VIEW teachers_view AS
SELECT
t.*,
iu.image as image
FROM teachers as t
LEFT JOIN id_user as iu WHERE t.id = iu.teacher_id;
read more about left join here
and in application use
supabase.from('teachers_view').select().neq('image', null);
This has now been implemented with PostgREST 9!
Here's an example:
const { data, error } = await supabase
.from('messages')
.select('*, users!inner(*)')
.eq('users.username', 'Jane'
In your, case you'd have to do id_user!inner(image)
Source: https://supabase.com/blog/postgrest-9#resource-embedding-with-inner-joins
query.not("your_column_name", "is", "NULL")
worked for me!
odd enough, if you want to check for NULL
.filter("your_column_name", "is", "NULL")
seems to be the solution. No idea why it's not consistent
It is not possible atm.
You can see state of issue here.
Some posibilities are using views o start the query in the other table.
The Supabase client uses postgrest, so you can use all sorts of operators in your queries. See this page as a reference.
This feature came up recently with the release of the support for PostgREST 9. You have to use !inner keyword, you can now filter rows of the top-level table.
const query = supabase.from(`teachers`).select(
`
*,
id_user!inner(image)
`
).not("id_users.image", "is", "NULL")
you can try like with inner joins by using the !inner operator in select
const query = supabase.from(`teachers`).select(
`
*,
id_user!inner(
image
)
`
)

TypeORM createQueryBuilder: Is possible to use table name as string instead of entity

In my current scenario, a third party will be creating tables dynamically on my DB, and storing the table name as a varchar and column names as jsonb in other table which is defined as an Entity in my NestJS backend.
This is so I can keep track (and query) these tables, since I have no control over its creation.
For this purpose I'd like to use TypeORM's createQueryBuilder instead of using raw queries as its easier for me to play with abstraction.
As far as I know TypeORMs createQueryBuilder needs a defined Entity in the from clause.
Something like this:
return await getManager()
.createQueryBuilder()
.select('*')
.from(MyDefinedModel, 'modelAlias')
.getRawMany();
}
So I'd like to do something like:
const tableName = await getDynamicallyGenetaredTableNames().getFirstOne()
// now tableName points to a string that is a table name, i.e 'table-data-192239'
return await getManager()
.createQueryBuilder()
.select('*')
.from(tableName, 'tableAlias')
.getRawMany();
So passing the table name I point to the right table, but TypeORM (and TS) complains because that tableName is a string, and not an Entity (Class) type
I really don't want to type-cast and start doing nasty things if there is something cleaner to achieve this.
I didn't find any solution in the official docs
Any brilliant ideas out there?
Thanks, y'all
We can pass table name instead of Entity for getRepository.
let tableName = 'user';
let query = getRepository(tableName).createQueryBuilder(tableName);
You can select from a table by its table name without defining an entity before like this:
const res = await manager
.createQueryBuilder()
.select()
.from("tableName", null)
.where("tableName.id = :id", { id: 1 })
.getRawMany();
Be sure that you set the second parameter of the from() explicitly to null.
You could try using a raw query:
import { getManager } from 'typeorm'
const tableName = await getDynamicallyGenetaredTableNames().getFirstOne()
// Use the table name in a raw SQL query
const result = await getManager().query(`SELECT * FROM ${tableName}`)

PostgreSQL: INSERT Error while reading data from CSV File

I am inserting values from a CSV file into a postgresql table, the code used to work fine earlier, but now that I'm on my local machine, it refuses despite so many different attempts.
const query =
"INSERT INTO questions VALUES (DEFAULT,$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12)";
questionData.forEach((row) => {
questions.push(
db.query(query, row).catch((err) => {
console.log(err);
})
);
});
This is my insertion logic, the questionData just holds every row of the CSV file, and questions is the array of promises which I Promise.all() in the end.
The Error I get is in this link
I am going crazy trying to fix this, I have changed absolutely nothing in the backend, my CSV files have only 12 rows which are the one's I'm trying to insert.
Edit:
What is 5+3,qwerty,mcq,chemistry,cat,cat,easy,2001,FALSE,nah,{8},"{7,2,8,3}"
What is 5+4,qwerty,mcq,maths,cat,cat,easy,2002,FALSE,nah,{9},"{7,9,5,3}"
What is 5+5,qwerty,mcq,physics,cat,cat,easy,2003,FALSE,nah,{10},"{7,2,10,3}"
What is 5+6,qwerty,mcq,chemistry,cat,cat,easy,2004,FALSE,nah,{11},"{11,2,5,3}"
What is 5+7,qwerty,mcq,maths,cat,cat,easy,2005,FALSE,nah,{12},"{7,2,12,3}"
What is 5+8,qwerty,mcq,physics,cat,cat,easy,2006,FALSE,nah,{13},"{13,2,5,3}"
What is 5+9,qwerty,mcq,chemistry,cat,cat,easy,2007,FALSE,nah,{14},"{7,14,5,3}"
What is 5+10,qwerty,mcq,maths,cat,cat,easy,2008,FALSE,nah,{15},"{7,2,15,3}"
This is my CSV
The error states that you're trying to push more values than the columns in your table.
i see your insert statement has a DEFAULT first parameter... what is that about?
If your target table has only 12 columns then you should be inserting the following
INSERT INTO questions VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12)

Adonis.js populate all with related tables data

I use MySql, all relationships have been configured correctly in models and schemas:
I have 3 tables:
1. posts ( main )
2. categories ( 1 post has 1 cat, 1 cat belongs to many posts )
3. tags ( many-to-many )
Categories and tags both have "post_id" column relating to "id" column in posts table.
What is the best way to get all related data ( post data + post category data + post tags data ) ?
( for now I know I can get something like:
const post = await Post.find(params.id)
const category = await post.categories().fetch()
etc for every related table
I'm sure there must be better way.
I'd like result to be:
{
post data - name, text ...,
"category": {
category data - name, text ...
},
"tags": [
{
tag1 data
},
{
tag2 data
}
]
}
const wantedData = await Post.query().where('id', params.id).with('categories').with('tags').fetch()
Yes, there is a better way to do this.
The Latest Adonis js Have the feature of the Query builder. You can perform almost all SQL queries using this. For Example
#select
Database
.from('users')
.select('id', 'username', 'email')
So There are many queries you can perform as your need. The following links will be very useful for you. Query builder Documentation

Categories

Resources