Запрос данных из другой таблицы, на которую ссылается внешний ключ, с помощью Sequelize и Postgres - PullRequest
0 голосов
/ 17 октября 2019

Я создаю приложение NextJs NodeJs Express с Postrges в качестве базы данных, я также использую два сервера и использую axios для получения и отправки запросов к моим конечным точкам API и от них.

У меня есть две таблицы: Компания и Банк. Первичный ключ из таблицы «Банк» упоминается в таблице «Компания» как внешний ключ. У компании может быть только один банк.

If I have a Bank table:
BankId    Bank Name    Account Number
1         New Bank     123456789

Company table:
CompanyId   Company Name    BankId
1           Newer Company   1

Я хочу показать данные для компании:

Company Name: Newer Company
Bank Name: New Bank
Account Number: 123456789 

Вот мои файлы:

Модель компании: модели /companyData.js

const Sequelize = require ('sequelize');
const db = require('../config/database');
const bank = require('./bank');

const companyData = db.define('companyData', {
    companyId: {
        type: Sequelize.INTEGER,
        primaryKey: true,
        autoIncrement: true
    },
    company_name: {
        type: Sequelize.STRING
    },
    bankId: {
        type: Sequelize.INTEGER,
        references: {
           model: 'bank', 
           key: 'bankId',
        }
    }
}, {
    freezeTableName: true
})

bank.hasOne(companyData);

module.exports = companyData;

Модель банка: models / bank.js

const Sequelize = require('sequelize');
const db = require('../config/database');

const Bank = db.define('bank', {
    bankId: {
        type: Sequelize.INTEGER,
        primaryKey: true,
        autoIncrement: true
    },
    bank_name: {
        type: Sequelize.STRING
    },
    account_number: {
        type: Sequelize.BIGINT
    }
}, {
    freezeTableName: true
})

module.exports = Bank;

Ниже представлен компонент, содержащий поля состояния и ввода для создания новой компании: components / newCompanyData.js

import React from 'react';
import axios from 'axios';

class newCompanyData extends React.Component {

        state = {
            company_name: '',
            bankId: '',
        }

    onChangeCompanyName = (e) => {
        this.setState({
            company_name: e.target.value
        })
    }

    onChangeBankId = (e) => {
        this.setState({
            bankId: e.target.value
        })
    }

    onSubmit = (e) => {
        e.preventDefault()

        axios.post('http://localhost:9000/api/company', {
            company_name: this.state.company_name,
            bankId: this.state.bankId,
        })
        .then(res => {
            console.log(res);
        }).catch(err => console.log(err))
    }

    onReset = (e) => {
        this.setState({
            company_name: '',
            bankId: '',
        })
    }

    render() {
        return (
            <div>
                <form>
                    Company name:<br/>
                    <input type="text" name="companyname" onChange={this.onChangeCompanyName} value={this.state.company_name}></input><br/>
                    Bank Id:<br/>
                    <input type="number" name="bankid" onChange={this.onChangeBankId} value={this.state.bankId}></input><br/>
                    <br/>
                    <button type="submit" onClick={this.onSubmit}>Submit</button><br/>
                    <input type="button" value="Reset Form" onClick={this.onReset} />
                </form>
            </div>
        )
    }
}

export default newCompanyData;

Затем я отправляю запрос на эту конечную точку API для создания таблицы, если она не существует, или просто заполняю новую строку: routs / api / company.js

const express = require('express');
const router = express.Router();
const DB = require('../../config/database');
const companyData = require('../../models/companyData');

router.post('/', (req, res) => {
    const data = req.body;

    DB.sync().then(function() {
        return companyData.create({
            company_name: data.company_name,
            bankId: data.bankId,
        });
      }).then(function () { 
          res.send(req.body);
          console.log('Success!')
      });
    })

module.exports = router;

Таким образом, он создает таблицу и заполняет все данные, однако проблема заключается в том, что я хочу напечатать все данные из таблицы компании, включая данные из банковской таблицы, на которую ссылается bankId: pages / viewCompany.js

import React from 'react';
import axios from 'axios';

class listCompany extends React.Component {

    state = {
        data: []
    }

    componentDidMount = () =>  {
        axios.get('http://localhost:9000/api/listcompany')
            .then((response) => {
                console.log(response.data);
                this.setState({data: response.data.response})
            }).catch(err => {
                console.log(err);
              });  
    }

    render() {
        return (
            <div>
                <h1>Company List</h1>
            </div>
        )
    }
}

export default listCompany;

Я отправил запрос на получение в эту конечную точку API, но он не возвращает его должным образом: routs / api / listcompany.js

const express = require('express');
const router = express.Router();
const Bank = require('../../models/bank');
const companyData = require('../../models/companyData');

router.get('/', (req, res) => {
        companyData.findAll({
            include: [{
            model: Bank
        }]}).then(function(response) {
            console.log(response);
            res.send({response});
          }).catch(function(err){
            console.log('Oops! something went wrong, : ', err);
          });
    })

module.exports = router;

У меня такое чувство, что я недостаточно хорошо его подключаюна этапе модели, а также при отправке запроса. Я ценю любую помощь, которую я могу получить. Спасибо.

Ответы [ 2 ]

0 голосов
/ 25 октября 2019

Мне наконец-то удалось решить эту проблему.

Я внес изменения в обе модели и в конечную точку API, где выполняется запрос для извлечения данных. Сначала я внес изменения в внешний ключ в модели companyData, переименовав его для дополнительных пояснений и объявив модель без скобок. Я также удалил все hasOne или принадлежащие для этой модели.

const Sequelize = require ('sequelize');
const db = require('../config/database');
const Bank = require('./bank');

const companyData = db.define('companyData', {
    companyId: {
        type: Sequelize.INTEGER,
        primaryKey: true,
        autoIncrement: true
    },
    company_name: {
        type: Sequelize.STRING
    },
    bankingId: {
        type: Sequelize.INTEGER,
        references: {
           model: Bank, 
           key: 'bankId',
        }
    }
}, {
    freezeTableName: true
})

module.exports = companyData;

Магия в модели банка. Если вы попытаетесь разделить hasOne и serveTo на две таблицы, это приведет к ошибкам, однако, если вы получите их в одном файле, все пройдет гладко. Обратите внимание, что это не работает без ограничений внешнего ключа.

const Sequelize = require('sequelize');
const db = require('../config/database');
const companyData = require('./companyData');

const Bank = db.define('bank', {
    bankId: {
        type: Sequelize.INTEGER,
        primaryKey: true,
        autoIncrement: true
    },
    bank_name: {
        type: Sequelize.STRING
    },
    account_number: {
        type: Sequelize.BIGINT
    }
}, {
    freezeTableName: true
})

Bank.belongsTo(companyData, {foreignKey: 'bankingId'});
companyData.hasOne(Bank, {foreignKey: 'bankId'});

Последнее изменение касалось конечной точки API, где я включил банк со всеми атрибутами:

const express = require('express');
const router = express.Router();
const Bank = require('../../models/bank');
const companyData = require('../../models/companyData');

router.get('/', (req, res) => {
        companyData.findAll({
          include: [{
            model: Bank,
            attributes: ['bankId', 'bank_name', 'account_number']  
          }],
        }).then(function(response) {
            console.log(response);
            res.send({response});
          }).catch(function(err){
            console.log('Oops! something went wrong, : ', err);
          });
    })
0 голосов
/ 20 октября 2019
const bank = require('./bank');

Это заявление не будет правильно импортировать модель банка. В дальнейшем, чтобы импортировать модель из определения модели, вы должны использовать sequelize.import( // path to file). Чтобы правильно импортировать модель, используйте следующее:

const bank = sequelize.import('./bank');

Примечание: Здесь seuqelize - это экземпляр Sequelize, а не сам класс. seuqelize переменная - это соединение с базой данных, которое вы создали, используя что-то вроде

const sequelize = new Sequelize(DB_NAME, DB_USERNAME, DB_PASSWORD, { ...options })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...