PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

A conexão com o postgres do typescript trava

AVISO


TLDS! (DEMASIADO TEMPO FAZER SKIM)! A resposta é longa e rica! Você pode deslizar! Está bem formatado!

Se você estiver com muita pressa !Você pode verificar Autenticar seção, Sequelize-typescript (não sequelize) seção, Sequelize-typescript seção.

E é melhor você ir diretamente para o INFERNO seção! Conheça o nodejs v14 HELL ! (Vá diretamente para o final! Bem, um pouco acima).

Verifique também FIX (Postgres v14 HELL)

Comecei e antes de saber me encontrei escrevi demais!

SUPER GUIA


Basicamente sequelize não deve apenas travar! Mas jogue um erro!

Examinando a fonte do código


Observando sync código aqui
 async sync(options) {
    // ...

    // no models defined, just authenticate
    if (!models.length) {
      await this.authenticate(options);
    } else {
      for (const model of models) await model.sync(options);
    }
    if (options.hooks) {
      await this.runHooks('afterBulkSync', options);
    }
    return this;
  }

Pode-se facilmente ver as possibilidades de suspensão!

Registro


Para depurar tais anomalias, antes de tudo, é importante ter um bom registro !

E você pode verificar como adicionar o registro aqui! Mesmo que normalmente o sequelize tenha o logging da query ativado por padrão!

https://sequelize.org/master/manual/getting-started.html #registro
const sequelize = new Sequelize('sqlite::memory:', {
  // Choose one of the logging options
  logging: console.log,                  // Default, displays the first parameter of the log function call
  logging: (...msg) => console.log(msg), // Displays all log function call parameters
  logging: false,                        // Disables logging
  logging: msg => logger.debug(msg),     // Use custom logger (e.g. Winston or Bunyan), displays the first parameter
  logging: logger.debug.bind(logger)     // Alternative way to use custom logger, displays all messages
});

Verifique a autenticação


Se não logar acontecer! Isso pode significar que o sequelize não fez nada e está apenas pendurado no início! Para testar a autenticação e se a conexão está funcionando!

Você pode testar com autenticar :

https://sequelize.org/master/manual/getting -started.html#testing-the-connection
try {
  console.log('Gonna authenticate'); // <== to make sure console.log is working and not overrided!
  await sequelize.authenticate();
  console.log('Connection has been established successfully.');
} catch (error) {
  console.error('Unable to connect to the database:', error);
}

Se você não conseguir logar! E Gonna authenticate impresso apenas ok! Então o processo está suspenso em autenticar . O que sugere um problema na autenticação!

Verifique suas credenciais


Certifique-se de que você não cometeu nenhum erro!

Verifique a conectividade do psql ou algum outro cliente externo

  • Se não funcionar! Isso sugere um problema com o servidor postgres! Ou alguma configuração!
  • Se funcionar! Então o problema está no nodejs! E seu programa!

NÃO ESQUEÇA DE INSTALAR O DRIVER POSTGRES (ou seu driver db)


De acordo com o documento:https://sequelize.org/master/manual/ Getting-started.html#installing
# One of the following:
$ npm install --save pg pg-hstore # Postgres
$ npm install --save mysql2
$ npm install --save mariadb
$ npm install --save sqlite3
$ npm install --save tedious # Microsoft SQL Server

Um dos comandos! Certifique-se de que você não esqueceu isso!

Compreendendo o que está acontecendo e depurando melhor! (registro de fonte de código)


A melhor maneira de depurar! E realmente determinar onde o problema está acontecendo! É adicionando registros ao código-fonte em si! Uma maneira rápida para mim é fazer isso diretamente em node_modules . Eu abri o git no repositório do sequelize! Fiz uma pesquisa! Determinado o local de sync , authenticate , query ! Todos residem em sequelize.js ! você pode verificar aqui ! Pode-se usar CTRL + F para acessar os métodos > authenticate( [adicione o ( ]. De qualquer forma! Você pode fazer o mesmo em node_modules ! E comece a adicionar logs! Você saberá em qual parte o problema está acontecendo! Que ajudam você a depurar o problema!

A outra maneira é fork ! E use seu garfo! E apenas trabalhar melhor!

Mas mmm! node_modules é uma maneira rápida ! Você pode fazer uma cópia ! também! Para garantir que você não perca seus logs! Assim que atualizar! No final limpo apenas removendo o módulo inteiro! E reinstale! Ou simplesmente inverta a criação dos logs (desfazer)! Acho uma maneira interessante de depurar!

Mas deve gerar um erro


Normalmente deveria! Ao ver a fonte do código você pode saber melhor! Normalmente, um erro deve ser lançado! Mas se um processo for enforcado! E nenhum erro é lançado! Então você pode esperar um resultado como este! Aqui pode estar faltando o driver! Verifique também se console.log . Está funcionando tudo bem! E a última coisa! MMM pode ser um problema com nodejs em si (veja a última seção).

Estou usando sequelize-typescript (não sequelize)


Muito importante saber! Sequelize-typescript é apenas um wrapper de sequela! Isso estava lá para adicionar suporte a texto datilografado! Ele fornece decoradores e alguns recursos! Também De sequelize v5! Typescript é suportado diretamente no sequelize! Veja aquihttps://sequelize.org/master/manual/typescript.html sequelize-typescript na versão mais recente! Virou-se para usar também os tipos de declaração nativa de sequelize!

Como sequelize-typescript wrap, sequelize! Certifique-se de verificar a documentação da sequela!

Observe também que algumas pessoas gritando :Não use decoradores! mmm! mmm! E outro mmmm!https://stackoverflow.com/a/60369189/7668448

Sequelize-typescript


Se você estiver usando sequelize-typescript, certifique-se de que a versão de sequelize-typescript e sequelize fazer corresponder ! De acordo com o documento V5 de sequela! Acho que V6 também deve fazer! E v1 para sequelize-typescript!
npm install [email protected] [email protected]

E não se esqueça dos pacotes necessários do typescript conforme o documento!
https:/ /www.npmjs.com/package/sequelize-typescript

(Você pode verificar e verificar todas essas informações no próprio documento)

Por que usar sequelize-typescript?


Como já mencionado! Sequelize tem suporte nativo para typescript a partir de V5 . Conforme aqui . Então, por que usar um wrapper acima dele! Que usam decoradores também! (Não sou contra decoradores! Alguns são! Conforme aqui )

Pergunte a si mesmo por quê? Existe alguma coisa para seqüelar texto datilografado! Uma vantagem importante em comparação com a forma nativa? Se houver coisas claras! Por favor, mencione-os nos comentários! E eu vou atualizar! Esta seção!

E se não! Nativo pode ser muito melhor! Uma dependência ou muitas em menos!

Configuração do projeto


tsconfig!
{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es6",
        "moduleResolution": "node",
        "rootDir": "./src",
        "outDir": "./dist",
        "lib": [
            "es2015",
            "es2016",
            "dom"
        ],
        "declaration": true,
        "experimentalDecorators": true,
        "esModuleInterop": true
    },
    "include": [
        "src/**/*"
    ],
    "exclude": [
        "node_modules/**/*",
        "src/**/*.test.tsx",
        "src/**/*.story.tsx",
        "test/**/*"
    ]
}

Essas são as duas coisas importantes a serem adicionadas.
"experimentalDecorators": true,
"esModuleInterop": true

Mas isso não deve ser problema seu! Caso contrário, o projeto lançará erros de compilação!

INFERNO

Versão do nó js (V14 HELL)


E sim! Essa pode ser a causa! Você já pode ter funcionado bem antes! E então em um novo computador ou ambiente! Não está mais funcionando !

A versão do nó pode ser o problema ! Nó v15 e Nó v14 ! Esse é um problema conhecido! Eu mesmo encontrei uma vez com knex.js e postgres (knex.js é um construtor de consultas)! Então você pode ver que está relacionado! Na minha história, o código estava funcionando bem no meu laptop e no vps antigo que implantamos! Mas então eu implantei em um windows rdp! E mmm! Estrondo! Então eu puxei meu cabelo por algum tempo! Refleti e verifiquei! Não houve mudança! E então eu vim para oi! Eu apenas atualizei o nodejs! E mais tarde descobri que outras pessoas encontraram a mesma coisa! Resumidamente! Tudo começou em nodejs v14 (eu chamo isso de v14 INFERNO )! Você pode conferir minha resposta sobre isso aqui

E aparentemente o mesmo problema está sempre lá com nodejs v15 !

Na questão deste tópico! Nós confirmamos isso! Na minha área de trabalho tudo funcionou bem! Nodejs v12 ! E com meu amigo computador! Não! nodejs v14 e nodejs v15 . Então eu queria confirmar! Eu instalei o nodejs v15 E caboom! BINGO! A execução simplesmente para inesperadamente! Sem registro! Sem erro! Em v12 ! Tudo estava funcionando corretamente! eu tinha erros no início, então eu corrigi-los! E o servidor estava funcionando! E sequela conectado ao DB!

Aqui as execuções

V12 e v13


Estou exibindo v13! O mesmo acontece com a v12!


nvm use v13
Now using node v13.14.0 (npm v6.14.4)
 [email protected]  ~/Documents/coderhero/Dev/projects/Fahima-ecommerce   LuckyLook  npm run dev 

> [email protected] dev /home/coderhero/Documents/coderhero/Dev/projects/Fahima-ecommerce
> npx ts-node-dev src/server.ts

[INFO] 01:49:29 ts-node-dev ver. 1.0.0 (using ts-node ver. 9.0.0, typescript ver. 4.0.5)
config ::::
{
  username: 'fahima',
  password: '123456',
  database: 'fahimashop',
  host: 'localhost',
  dialect: 'postgres'
}
hi there ::::
Executing (default): SELECT 1+1 AS result
connection established
Executing (default): CREATE TABLE IF NOT EXISTS "Products" ("id"   SERIAL , "brand" TEXT, "price" DECIMAL, "description" VARCHAR(255), "imgUrl" VARCHAR(255), "category" VARCHAR(255), "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, PRIMARY KEY ("id"));
Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'Products' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
server running http://localhost:8100
press CTRL+C to stop server, please :)

Legal funcionando sem problemas

Execução de V14 e v15

v14



 [email protected]  ~/Documents/coderhero/Dev/projects/Fahima-ecommerce   LuckyLook  node -v        
v14.15.0
 [email protected]  ~/Documents/coderhero/Dev/projects/Fahima-ecommerce   LuckyLook  npm run dev

> [email protected] dev /home/coderhero/Documents/coderhero/Dev/projects/Fahima-ecommerce
> npx ts-node-dev src/server.ts

[INFO] 02:07:35 ts-node-dev ver. 1.0.0 (using ts-node ver. 9.0.0, typescript ver. 4.0.5)
config ::::
{
  username: 'fahima',
  password: '123456',
  database: 'fahimashop',
  host: 'localhost',
  dialect: 'postgres'
}
hi there ::::
 [email protected]  ~/Documents/coderhero/Dev/projects/Fahima-ecommerce   LuckyLook  

E ops! O programa está saindo inesperadamente sem saída de erro!

V15



 [email protected]  ~/Documents/coderhero/Dev/projects/Fahima-ecommerce   LuckyLook  nvm use v15    
Now using node v15.0.1 (npm v7.0.3)
 [email protected]  ~/Documents/coderhero/Dev/projects/Fahima-ecommerce   LuckyLook  npm run dev

> [email protected] dev
> npx ts-node-dev src/server.ts

[INFO] 02:10:48 ts-node-dev ver. 1.0.0 (using ts-node ver. 9.0.0, typescript ver. 4.0.5)
config ::::
{
  username: 'fahima',
  password: '123456',
  database: 'fahimashop',
  host: 'localhost',
  dialect: 'postgres'
}
hi there ::::
 [email protected]  ~/Documents/coderhero/Dev/projects/Fahima-ecommerce   LuckyLook  

E oppsii novamente! O programa está saindo inesperadamente sem saída de erro!

Também não há diferença entre v14 e v15 ! É V14 HELL .

Resumindo


O INFERNO V14 é uma causa conhecida e muito provável! Há um problema com pg módulo eu acho! Algo mudou na v14 e causou esse problema!

Resumindo! Se nada faz sentido! E se o seu mesmo código estava funcionando antes! Primeira coisa a fazer! É verificar com nodejs v13 ou v12 ! Isso pode salvá-lo da insanidade! Quem diria que a versão do nodejs e uma nova criariam tal problema!

O que é esse problema! O que é V14 HELL em nodejs?


Se como eu você gosta de saber os detalhes e o que aconteceu!?

Com nó V14! Algumas mudanças importantes aconteceram na API! Também muitas coisas foram mudadas! Incluindo a versão Openssl!

Para postgres! E pg módulo! O problema foi descrito neste comentário por este tópico :

E de acordo com este PR !

Você pode ver as alterações esta diferença

Resumindo como mencionado! O comportamento para onReadySate alterado para net.Socket !E a solução implementada foi não usar onReadyState de forma alguma!

E conforme isso

Verifique esta linha

Na versão mais antiga, a conexão era chamada apenas se o soquete estiver em closed Estado! readyState o uso é eliminado!

Você pode entender! Dependendo da implementação! Muitas coisas podem ou não ser afetadas por essas mudanças fundamentais!

Mudanças de nós relevantes


E porque eu queria ver onde a mudança aconteceria! Aqui você vai e pode verificar

https://github.com/nodejs/node/pull/32272

Pode-se verificar o log de alterações também:

https://github.com/nodejs/node/blob /master/doc/changelogs/CHANGELOG_V14.md

CORREÇÃO (Inferno do Postgres v14)


De acordo com minha resposta aqui .

Atualizar pg driver para >=8.0.3 ! Você pode simplesmente atualizar para o mais recente!
npm install [email protected] --save

E você pode verificar o nosso problema em questão

Versão antiga em v7



Atualizando para v8



Executando novamente com node v15



Taraaaaa! E funcionou maravilhosamente!

E se você não estiver usando postgres ! E o problema era v14 HELL ! Significado Você testou com v13 . E funcionou! Em seguida, tente atualizar seu driver db para o mais recente!

Por que nó v14 + saída e nenhum erro de registro


Também para mencionar as mudanças de quebra! Feito pg faça o processo sair na chamada connect() call . E foi isso que o fez sair! E o registro era para ser visto! Mais detalhes para isso! Aqui como aconteceu! Sequelize tem a implementação do dialeto postgres! Que usam pg! E pg cliente! crie uma conexão! A conexão tem um connect evento! Quando conecta, emite! E porque o nó v14 muda o comportamento para começar com aberto! A conexão de fluxo foi ignorada! E o fluxo é considerado conectado! Onde não é! E o connect evento é emitido diretamente! Quando isso acontecer! O cliente chamará requestSsl() ou startup() método do objeto de conexão! E ambos chamarão this._stream.write . porque o fluxo não está conectado! Aconteceu um erro! Este erro não é captura! Então a promessa de seqüenciar driver! Vai ficar sem solução! E então o loop de eventos fica vazio! Nodejs por comportamento padrão apenas saia!

Você pode ver o passo através das linhas de código:

Por que o nodejs sai (promessas não resolvidas)


https://github.com/nodejs/node/issues/22088

O nó sai sem erro e não aguarda promessa (retorno de chamada de evento)

o que acontece quando uma promessa nunca é resolvida?

NVM


https://github.com/nvm-sh/nvm

Se você não sabe o que nvm é! Ou você não está usando nvm . Considere usá-lo! Como é uma ferramenta muito interessante! Nvm é uma ferramenta de gerenciamento de versão do nó !

Com nvm mudando, depurando e testando para e com diferentes versões do nodejs! É rápido e uma brisa! E assim instalando novas versões do nodejs em paralelo!

Observação sobre sequelize.sync()


Não use para production ! Ou em tudo! (A maioria dos ORM! E o construtor de consultas (knex.js) usam migrações).

https://sequelize.org/master/manual/model -basics.html#synchronization-in-production

Do documento