Foreignkey error with Sqlalchemy

Asked

Viewed 149 times

1

Basically what I want is for him to register in Transaction() the Account he sends and the Account he receives the amount. However I am not able to link the two Foreign key with the accounts I am going through.

from sqlalchemy.orm import relationship
from sqlalchemy import Column, Integer, Unicode, ForeignKey, DateTime
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base


Session = sessionmaker()
s = Session()
engine = create_engine('sqlite:///database.db')
Base = declarative_base(bind=engine)


class Transaction(Base):
    __tablename__ = 'transactions'
    FROM = Column('from',ForeignKey('accounts.id'), back_populates='transactions')
    TO = Column('to',ForeignKey('accounts.id'), back_populates='transactions')
    id = Column('id',Integer(), primary_key=True, unique=True, nullable=False)
    AMOUNT = Column('amount',Integer())
    TYPE = Column('type',Integer())
    date = Column('date',DateTime())

    def __init__(self, FROM, TO, TYPE, AMOUNT):
        self.FROM = FROM
        self.TO = TO
        self.TYPE = TYPE
        self.AMOUNT = AMOUNT
        s.add(self)
        self.transaction(TYPE, AMOUNT)


    def transaction(self, type, value):
        if type == 0:
            self.TO._decrease(value)
        elif type == 1:
            self.TO._increase(value)


class Account(Base):
    __tablename__ = 'accounts'
    id = Column('id', Integer, primary_key=True, unique=True)
    owner = Column('owner', Unicode(40))
    cpf = Column('cpf', Unicode(11), unique=True)
    balance = Column('balance', Integer())
    transactions = relationship("Transaction", backref='account')

    def __init__(self,owner,cpf,balance=0):
        self.owner = owner
        self.cpf = cpf
        self.balance = balance
        s.add(self)
        self.id = s.query(Account).filter(Account.cpf == self.cpf).first().id

    def _increase(self, amount):
        self.balance += amount

    def _decrease(self, amount):
        self.balance -= amount

    def __str__(self):
        return f'AccID: {self.id} | Owner: {self.owner} | CPF: {self.cpf} | Balance: ${self.balance:.2f}'

    def __repr__(self):
        return f'<{self.__class__.__name__}:{self.owner}>'


Base.metadata.create_all()
if __name__ == '__main__':
    acc = Account(owner='Thomas', cpf=12345678901, balance=0)
    Transaction(acc,acc,1,500)
    print(acc.balance)
    query = s.query(Transaction).first()
    print(query)

Error:

sqlalchemy.exc.AmbiguousForeignKeysError: Could not determine join condition between parent/child tables on relationship Account.transactions - there are multiple foreign key paths linking the tables.  Specify the 'foreign_keys' argument, providing a list of those columns which should be counted as containing a foreign key reference to the parent table.

1 answer

1


According to what is in the Sqlalchemy documentation, in situations like this you need to explicitly define foreign keys that correspond to reverse mapping from the class Account:

In short, you should declare

transactions = relationship("Transaction", backref='account')

as

transactions = relationship("Transaction", foreign_keys=[Account.FROM,Account.TO]).

Browser other questions tagged

You are not signed in. Login or sign up in order to post.