Flask sqlalchemy relations across multiple files

2024/11/18 11:42:58

I'm new to Flask Sqlalchemy and I want to declare multiple models and relate them to each other, I followed the example in the documentation but I keep getting this error

sqlalchemy.exc.InvalidRequestError: When initializing mapper mapped class Organization->organizations,
expression 'User' failed to locate a name ('User').
If this is a class name,
consider adding this relationship()
to the <class 'models.Organization.Organization'>
class after both dependent classes have been defined

I don't want to store all my models in one files as the project might get bigger and bigger with time, so I've created the following structure:

- models
--- __init__.py
--- User.py
--- Organization.py
--- ...
- manage.py
- app.py

I want the user to belong to an Organization, and the Organization has many users, also I want the Organization to have an optional field for itself reflexive relationship, here is what I've tried.

init.py

from .Attachment import Attachment
from .Invoice import Invoice
from .Organization import Organization
from .Setting import Setting
from .Transaction import Transaction
from .User import User

User.py

from app import db, ma
from marshmallow_enum import EnumField
import enum
import bcryptclass RuleEnum(enum.Enum):admin = 'admin',collector = 'collector'retailer = 'retailer'vendor = 'vendor'vendor_admin = 'vendor_admin'class User(db.Model):__tablename__ = 'users'id = db.Column(db.Integer, primary_key=True)name = db.Column(db.String(), nullable=False)mobile = db.Column(db.String(), nullable=False)username = db.Column(db.String(), unique=True, nullable=False)password = db.Column(db.TEXT(), nullable=False)is_active = db.Column(db.Boolean(), default=False)rule = db.Column(db.Enum(RuleEnum), nullable=False)created_on = db.Column(db.DateTime, server_default=db.func.now())updated_on = db.Column(db.DateTime, server_default=db.func.now(), server_onupdate=db.func.now())# relations#related fieldsorganization_id = db.Column(db.Integer, db.ForeignKey('organizations.id'), nullable=True)def __init__(self,name,username,mobile,password,rule,is_active,organization_id = None):self.name = nameself.username = usernameself.mobile = mobileself.rule = ruleself.is_active = is_activeself.organization_id = organization_idself.password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode()def __repr__(self):return "<id %s>" % self.idclass UserSchema(ma.SQLAlchemyAutoSchema):rule = EnumField(RuleEnum, by_value=True)class Meta:exclude = ['password']model = Userload_instance = True

Organization.py

from app import db, ma
import enum
from marshmallow_enum import EnumFieldclass TypeEnum(enum.Enum):vendor = 'vendor'retailer = 'retailer'class Organization(db.Model):__tablename__ = 'organizations'id = db.Column(db.Integer, primary_key=True)name = db.Column(db.String())cr = db.Column(db.String(), unique=True)location = db.Column(db.String())is_request_approved = db.Column(db.Boolean(), default=False)is_active = db.Column(db.Boolean(), default=False)type = db.Column(db.Enum(TypeEnum))created_on = db.Column(db.DateTime, server_default=db.func.now())updated_on = db.Column(db.DateTime, server_default=db.func.now(), server_onupdate=db.func.now())# relations# virtual columnsparent = db.relationship('Organization', remote_side=id, backref='sub_organizations')users = db.relationship('User', backref='organization')# related fieldsparent_id = db.Column(db.Integer, db.ForeignKey('organizations.id'), nullable=True)def __init__(self,name,cr,location,is_request_approved,is_active,type,parent_id = None):self.name = nameself.cr = crself.location = locationself.is_request_approved = is_request_approvedself.is_active = is_activeself.type = typeself.parent_id = parent_iddef __repr__(self):return "<id %s>" % self.idclass OrganizationSchema(ma.SQLAlchemyAutoSchema):type = EnumField(TypeEnum, by_value=True)class Meta:model = Organizationload_instance = True

Regarding the migrations I've followed a blog post and made the manage.py file with this code

manage.py

import osfrom flask_sqlalchemy import SQLAlchemy
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommandfrom app import app, dbapp.config.from_object(os.environ['APP_SETTINGS'])
migrate = Migrate(app, db)
manager = Manager(app)manager.add_command('db', MigrateCommand)if __name__ == '__main__':manager.run()
Answer

For future reference I solved it by arranging the import statements in my __init__.py file, so that any class that might be referred to in a relationship shall be imported before so in my case I had to change the __init__.py file to the following

from .User import User # User class is imported before it's referenced in the Organization model
from .Attachment import Attachment
from .Invoice import Invoice
from .Organization import Organization
from .Setting import Setting
from .Transaction import Transaction

it's not the ideal solution I'm sure there's a better way so any other/better approach is welcomed for future references.

https://en.xdnf.cn/q/118685.html

Related Q&A

Parsing XML with Pykml

I have the following xml file I got from QGIS<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.…

Python Google App Engine Receiving a string in stead of JSON object

I am sending a HTTP POST request from android to a server using the script belowURI website = new URI("http://venkygcm.appspot.com");HttpClient client = new DefaultHttpClient();HttpPost reque…

Creating Gui for python client server

Help needed with my python project. Unable to get the code for the client or server implemented with the Gui i created. it is one based on book seller where the client is the buyer and the server is th…

Maximum Subarray sum - Where is my solution wrong? Kadanes Algorithm

Here is a description of the problem:The maximum sum subarray problem consists in finding the maximum sum of a contiguous subsequence in an array or list of integers: max_sequence([-2, 1, -3, 4, -1, 2,…

Pandas: Selecting rows and columns based on a subset of columns that contain a certain value

Lets say I have a dataframe with column names as follows:col_id_1, col_id_2, ..., col_id_m, property_1, property_2 ..., property_nAs an example, how would I search across all col_ids for, say, the valu…

Open a image file then display it in new window

I have a button in my GUI then after selecting a image file I want it to display in new window.Code:import tkinter as tk from tkinter import * from tkinter import ttk from tkinter import filedialog …

python plotting chart in interactive viewer vscode

This works and shows a plot in vscode: #%% cell with plot import matplotlib.pyplot as plt y = [3.2, 3.9, 3.7, 3.5, 3.02199] x = [0.15, 0.3, 0.45, 0.6, 0.75] n = [155, "outliner", 293, 230, 67…

Find all lines in a dataframe that matches specific pattern and extract the strings after split

I have a dataframe that looks like LineEntry: [0x0000000002758261-0x0000000002758268): /a/b/c:7921:14 LineEntry: [0x0000000002756945-0x0000000002756960): /f/b/c:6545:10 LineEntry: [0x00000000027562c9-0…

Python: Concatenate many dicts of numpy arrays with same keys and size

I have a function called within a loop that returns a dict (dsst_mean) with roughly 50 variables. All variables are numpy arrays of length 10.The loop iterates roughly 3000 times. Im current concatenat…

intersection of 2 objects of different types

i want to take the intersection of: ((e, 13.02338360095244), (a, 11.820318700775383), (o, 9.20172171683253), (s, 7.635081506807498), (n, 7.547469320471335), (i, 7.219915745772025), (r, 6.70492704072287…