Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In SQLAlchemy, how do I create a ForeignKey relationship across 2 different .py files?

In user_models.py, I have this:

class Users(Base):
    __tablename__ = 'account_users'
    id = Column(Integer, primary_key = True)
    username = Column(String(255), nullable=False)    
Base.metadata.create_all(engine)

When I run this, I create a user table.

On my other file, groups_models.py, I have this:

class Groups(Base):
    __tablename__ = 'personas_groups'
    id = Column(Integer, primary_key = True)
    user_id = Column(Integer, ForeignKey('account_users.id')) #This creates an error!!!
    user = relationship('Users') #this probably won't work. But haven't hit this line yet.

Base.metadata.create_all(engine)

So, as you can see, I want to put a many-to-one relationship from groups -> users.

But when I run groups_models.py...I get this error:

sqlalchemy.exc.NoReferencedTableError: Foreign key associated with column 'personas_groups.user_id' could not find table 'account_users' with which to generate a foreign key to target column 'id'

If I put the two tables together in one file, I'm sure it could work...but because I split it into 2 files (which I absolutely have to)...I don't know how to make ForeignKey relationships work anymore?

like image 465
TIMEX Avatar asked Nov 24 '11 20:11

TIMEX


People also ask

How do I create a many to many relationship in SQLAlchemy?

Many to Many relationship between two tables is achieved by adding an association table such that it has two foreign keys - one from each table's primary key.

How do you create a one to many relationship in flask SQLAlchemy?

The comments class attribute defines a One-to-Many relationship between the Post model and the Comment model. You use the db. relationship() method, passing it the name of the comments model ( Comment in this case). You use the backref parameter to add a back reference that behaves like a column to the Comment model.


1 Answers

The key is to use the same Base for both foreign keys, instead of creating a new one for each table.

basetest.py

from sqlalchemy import create_engine, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, backref
from sqlalchemy import Column, Integer, String
from sqlalchemy import Table, Text

engine = create_engine('mysql://test:test@localhost/test1',
                    echo=False)

Base = declarative_base()

user_models.py

from sqlalchemy import Column, Integer, String
from sqlalchemy import Table, Text


#Base = declarative_base()
from basetest import Base

class Users(Base):
    __tablename__ = 'account_users'
    __table_args__ = {'extend_existing':True}
    id = Column(Integer, primary_key = True)
    username = Column(String(255), nullable=False)    

Base.metadata.create_all(engine)

groups_models.py

from sqlalchemy import create_engine, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, backref
from sqlalchemy import Column, Integer, String
from sqlalchemy import Table, Text

from basetest import Base
#Base = declarative_base()
from test1 import Users

class Groups(Base):
    __tablename__ = 'personas_groups'
    __table_args__ = {'extend_existing':True}
    id = Column(Integer, primary_key = True )
    user_id = Column(Integer, ForeignKey('account_users2.id')) #This creates an error!!!
    user = relationship(Users) #this probably won't work. But haven't hit this line yet.

Base.metadata.create_all(engine)

Make sure that you have same Base to create all related tables.

like image 145
Nilesh Avatar answered Sep 20 '22 05:09

Nilesh