Insert record in mysql with adonisjs jsonb field - javascript

I'm trying to insert a record where one of the fields is of type JSONB
Below is the format I'm trying to build and at the end the error that is being issued.
The field in question is veiculo
orm is trying to access the inside of the json to try to indetify the field.
It should insert the complete object.
I thank the attention. Thanks.
Post
{
veiculo: {
placa: 'PLACA',
motorista: 'NOME',
contato: 'CONTATO',
casa: true,
horaEntrada: '2022-01-20T05:02:22.000Z'
},
fornecedor: 'ALIMENTOS',
lab: 'sim',
}
Model
import { DateTime } from 'luxon'
import { BaseModel, column } from '#ioc:Adonis/Lucid/Orm'
export default class Produto extends BaseModel {
#column({ isPrimary: true })
public id: number
#column()
public fornecedor: string
#column()
public lab: string
#column()
public veiculo: Object
#column.dateTime({ autoCreate: true })
public createdAt: DateTime
#column.dateTime({ autoCreate: true, autoUpdate: true })
public updatedAt: DateTime
Migration
public async up () {
this.schema.createTable(this.tableName, (table) => {
table.increments('id')
table.string('fornecedor'
table.string('lab')
table.jsonb('veiculo')
/**
* Uses timestamptz for PostgreSQL and DATETIME2 for MSSQL
*/
table.timestamp('created_at', { useTz: true })
table.timestamp('updated_at', { useTz: true })
})
}
Error
Error: ER_BAD_FIELD_ERROR: Unknown column 'placa' in 'field list'

Resolved with await dataNfe.related('items').createMany(items)

Related

Adonis js loading only first preload

Im trying to list the itens of Chamados and the respective users, but only the first chamado return the user.
Model Usuario:
export default class Usuario extends BaseModel {
#hasMany(() => Chamado)
public chamados: HasMany<typeof Chamado>
#column({ isPrimary: true })
public id: number
#column()
public nome: string
#column()
public nivel: number
#column()
public email: string
#column()
public senha: string
#column.dateTime({ autoCreate: true })
public createdAt: DateTime
#column.dateTime({ autoCreate: true, autoUpdate: true })
public updatedAt: DateTime
}
Model Chamado:
export default class Chamado extends BaseModel {
#belongsTo(() => Usuario, {
foreignKey: 'id'
})
public user: BelongsTo<typeof Usuario>
#column({ isPrimary: true })
public id: number
#column()
public titulo: string
#column()
public descricao: string
#column()
public url_erro: string
ChamadosController
// Get chamados
public async index() {
const chamados = await Chamado.query().preload('user')
return {
data: chamados,
}
}
is returning 'user' only in first result:
result from get

TypeORM relations and express

I'm making Many to One, One to many relations with TypeORM and MySQL, and Express. There are two tables cold post and user.
One user has many posts. and each post has one user.
I would like to use 'userUuid' column as a foreign key to join these two tables.
Can anybody tell me how to fix it?
Thank you
// user
import {
Entity,
PrimaryGeneratedColumn,
Column,
BaseEntity,
BeforeInsert,
Generated,
OneToMany,
} from 'typeorm'
import { v4 as uuid } from 'uuid'
import { Post } from './Post'
#Entity()
export class User extends BaseEntity {
#PrimaryGeneratedColumn()
id!: number
#Column()
userId!: string
#Column()
#Generated('uuid')
userUuid!: string
#Column({ nullable: true })
displayName!: string
#Column({ nullable: true })
email!: string
#OneToMany(() => Post, (post: Post) => post.user)
posts!: Post[]
#BeforeInsert()
createUuid() {
this.userUuid = uuid()
}
toJSON() {
return { ...this, id: undefined }
}
}
// post
import {
Entity,
PrimaryGeneratedColumn,
CreateDateColumn,
UpdateDateColumn,
Column,
BaseEntity,
Generated,
BeforeInsert,
ManyToOne,
JoinColumn,
} from 'typeorm'
import { v4 as uuid } from 'uuid'
import { User } from './User'
#Entity()
export class Post extends BaseEntity {
#PrimaryGeneratedColumn()
id!: number
#Column()
#Generated('uuid')
postUuid!: string
#Column({ nullable: true })
userUuid!: string
#CreateDateColumn({ nullable: true })
createdAt!: Date
#UpdateDateColumn({ nullable: true })
updatedAt!: Date
#Column({ nullable: true })
content!: string
#BeforeInsert()
createUuid() {
this.postUuid = uuid()
}
#ManyToOne(() => User, (user: User) => user.posts)
user!: User
#JoinColumn([{ name: 'userUuid' }, { referencedColumnName: 'userUuid' }])
toJSON() {
return { ...this, id: undefined }
}
}
//express
router
.route('/')
.get((req: Request, res: Response) => {
User.find({ relations: ['posts'] })
.then((data) => {
res.send(data)
})
.catch((err) => res.send(err))
})
//express
router
.route('/')
.get((req: Request, res: Response) => {
Post.find({ relations: ['user'] })
.then((data) => {
res.send(data)
})
.catch((err) => res.send(err))
})
Seems like you need to use JoinColumn decorator.
class Post /*...*/ {
/*...*/
#ManyToOne(() => User)
#JoinColumn({ referencedColumnName: "userUuid" })
userUuid!: string;
/*...*/
}
From TypeORM docs
Join columns are always a reference to some other columns (using a foreign key). By default your relation always refers to the primary column of the related entity. If you want to create relation with other columns of the related entity - you can specify them in #JoinColumn as well:
#ManyToOne(type => Category)
#JoinColumn({ referencedColumnName: "name" })
category: Category;
The relation now refers to name of the Category entity, instead of id. Column name for that relation will become categoryName.

Adonis JS v5 relationship missing model attribute

I am learning how to use the Adonis framework (v5) and as the tradition dictates it, I am creating a todo list api to test it out.
The problem I am having is regarding the relationship between the User and Todo entities.
Here are the two models:
// file: app/Models/Todo.ts
export default class Todo extends BaseModel {
#column({ isPrimary: true })
public id: number
#belongsTo(() => User, {
foreignKey: 'id',
})
public author: BelongsTo<typeof User>
#column()
public completed: boolean
#column()
public title: string
#column()
public description: string | null
#column.dateTime({ autoCreate: true })
public createdAt: DateTime
#column.dateTime({ autoCreate: true, autoUpdate: true })
public updatedAt: DateTime
}
// file: app/Models/User.ts
export default class User extends BaseModel {
#column({ isPrimary: true })
public id: number
#column()
public username: string
#column({ serializeAs: null })
public password: string
#hasMany(() => Todo, {
foreignKey: 'author',
})
public todos: HasMany<typeof Todo>
#column.dateTime({ autoCreate: true })
public createdAt: DateTime
#column.dateTime({ autoCreate: true, autoUpdate: true })
public updatedAt: DateTime
#beforeSave()
public static async hashPassword(user: User) {
if (user.$dirty.password) {
// Only hash password if required
user.password = await Hash.make(user.password)
}
}
}
I did not include the migrations files but I will edit this question if they are needed.
What I am expecting is that I should be able to create and save Users into my database, the same for Todo entries and link the todo entries to their author. The documentation provides us with an example but I don't see where I am doing something wrong.
So to test it out I am using the node ace repl command as follow:
// log of running the commands in the AdonisJS v5 REPL
> loadModels()
recursively reading models from "app/Models"
Loaded models module. You can access it using the "models" variable
> undefined
> const testUser = await models.User.create({ username: 'testUser', password: 'password' })
undefined
> await testUser.related('todos').create({ title: 'Example todo entry' })
Uncaught:
Exception: E_MISSING_MODEL_ATTRIBUTE: "User.todos" expects "author" to exist on "Todo" model, but is missing
at <my-app-directory>\REPL23:1:39
at Proxy.related (<my-app-directory>\node_modules\#adonisjs\lucid\build\src\Orm\BaseModel\index.js:1436:18)
at HasMany.boot (<my-app-directory>\node_modules\#adonisjs\lucid\build\src\Orm\Relations\HasMany\index.js:74:12)
at KeysExtractor.extract (<my-app-directory>\node_modules\#adonisjs\lucid\build\src\Orm\Relations\KeysExtractor.js:28:39)
at Array.reduce (<anonymous>)
at <my-app-directory>\node_modules\#adonisjs\lucid\build\src\Orm\Relations\KeysExtractor.js:32:23
>
I don't understand the error message since author actually exists on the Todo model.
How can I solve this problem and get my todo app up and running?
Thank you by advance!
The error is that you are missing a field inside your model.
You need to define all fields with the #column() decorator. In your example, you are not defining the column author.
When creating a relation, you must have one column (the FK) and one relation.
If we assume that you have a column user_id inside your todos table, then you need to add the column user_id inside your Todo model.
Here is a correct example:
class User extends BaseModel {
// ...
#hasMany(() => Todo)
todos: HasMany<typeof Todo>
}
class Todo extends BaseModel {
#column()
user_id: number
#belongsTo(() => User)
author: BelongsTo<typeof User>
}

How to write nested DTOs in NestJS

I am a beginner in NestJS and I want to write a DTO for below structure -
{
something: {
info: {
title: string,
score: number,
description: string,
time: string,
DateOfCreation: string
},
Store: {
item: {
question: string,
options: {
item: {
answer: string,
description: string,
id: string,
key: string,
option: string
}
}
}
}
}
}
I want to write a DTO for that nested Data object. I can't find a solid example for writing nested DTO in NestJS. I am a beginner in NestJS and I have never worked with DTO before. So please don't assume that I know something. I am using it with Mongoose.
You will have to create separate classes for each object in your schema and a main class which will import all the classes.
class Info {
readonly title:string
readonly score:number
readonly description:string
readonly dateOfCreation:Date
}
export class SampleDto {
#Type(() => Info)
#ValidateNested()
readonly info: Info
...Follow same for the rest of the schema
}
Refer: https://github.com/typestack/class-validator#validating-nested-objects
//example :
export class UserBaseDto {
#ApiProperty({
type: String,
required: true,
description: 'email user, minlength(4), maxlength(40)',
default: "test#email.com",
})
#IsString()
#MinLength(4)
#MaxLength(40)
#IsNotEmpty()
email: string;
//....enter code here
}

TypeORM Throwing Duplication Error on Bulk saving instead of ignore or update existing value

As Documented on TypeOrm FrameWork Repository.save should save/insert new values and ignore/update the existing once,
But now I'm facing a problem that it's thrown a duplication error on existing value and stoping the whole inserting! ( I have a unique column called key )
My entity:
import { Entity, Column, PrimaryGeneratedColumn, ManyToOne, JoinColumn, PrimaryColumn } from 'typeorm';
import { Source } from '../sources/source.entity';
#Entity({ name: 'articles' })
export class Article {
#PrimaryGeneratedColumn()
id: number;
#Column()
title: string;
#Column({
nullable: true
})
image: string | null;
#Column({
type: "text",
})
url: string;
#Column({
type: "varchar",
unique: true
})
key: string;
#Column({
type: 'datetime',
nullable: true
})
date: Date | null;
#ManyToOne(type => Source, source => source.articles, {eager: true})
#JoinColumn({name: 'source'})
source: Source;
#Column({
type: `text`,
nullable: true
})
description: string | null
}
My Service:
constructor(
#InjectRepository(Article) private readonly articleRepository: Repository<Article>,
private readonly articlesScraper: BlogScraperService
) {
}
async clonningFromScraper() {
let articles = await this.articlesScraper.articles('1');
articles = articles.map(article => ({ ...article, key: decodeURIComponent(article.url).substring(0, 255) }));
return this.articleRepository
.save(articles);
}
I have ended up solving this by RAW SQL query using the following
return this.articleRepository.query(
"INSERT IGNORE INTO articles ( title, date, url, image, source, description, _key ) VALUES ?", [querableArticles]);

Categories