flask_sqlalchemy relationship proble, - python

I have postgres db with some data, i can do everything i want until i add relation to Employee and EmployeeExperience, then a get an error lok like:
InvalidRequestError: One or more mappers failed to initialize - can't proceed with initialization of other mappers. Triggering mapper: 'mapped class EmployeeExperience->employee_experience'. Original exception was: Mapper 'mapped class Employee->employee' has no property 'employee_experience'
I read a lot of tutorials and don't unerstand what i did wrong, any solution doesn't work for me, pls help, here is my code.
import psycopg2
import datetime
# <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
from flask import Flask
from flask_bcrypt import Bcrypt
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = "postgres://postgres:postgres#localhost:5433/db_name"
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy()
db.init_app(app)
flask_bcrypt = Bcrypt()
flask_bcrypt.init_app(app)
app.app_context().push()
# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
# <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< models
class Employee(db.Model):
__tablename__ = "employee"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
surname = db.Column(db.String(200))
first_name = db.Column(db.String(200))
birth_date = db.Column(db.Date)
email = db.Column(db.String(300), unique=True)
city = db.Column(db.String(200))
latitude = db.Column(db.Float)
longitude = db.Column(db.Float)
male = db.Column(db.Integer)
registered_on = db.Column(db.DateTime)
active = db.Column(db.Integer)
_password = db.Column(db.String(400))
employee_experience = db.relationship("EmployeeExperience", back_populates="employee")
class EmployeeExperience(db.Model):
__tablename__ = "employee_experience"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
position = db.Column(db.String(300))
company = db.Column(db.String(200))
city = db.Column(db.String(200))
description = db.Column(db.Text)
desc_raw = db.Column(db.Text)
employee_id = db.Column(db.Integer, db.ForeignKey('employee.id'))
employee = db.relationship("Employee", back_populates="employee_experience")
# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
emp = Employee.query.first()

'mapped class Employee->employee' has no property 'employee_experience'
The error cause is clearly stated. You have not defined the employe_experience attribute yet on your Employee model

Related

How to configure SQLAlchemy relationships with more than one relationship column? [duplicate]

I'm struggling to configure my relationships for this database. I can't quite get my head around these relationships and foreign keys and how it all fits together.
I'm trying to have a user who can have multiple posts and multiple projects, but get "primaryjoin" errors ever since I had more than one relationship in the User class.
I would appreaciate any help, I know there have been similar questions asked but I can't seem to map those solutions to my own application.
Here is my models.py file:
from flask_sqlalchemy import SQLAlchemy
from flask_login import UserMixin
from uuid import uuid4
import datetime
from api import app
db = SQLAlchemy(app)
def get_uuid():
return uuid4().hex
today = datetime.date.today()
next_week = today + datetime.timedelta(days=7)
class User(UserMixin, db.Model):
__tablename__ = "users"
id = db.Column(db.String(32), primary_key=True, unique=True, default=get_uuid)
name = db.Column(db.String(60))
email = db.Column(db.String(345), unique=True)
password = db.Column(db.Text, nullable=False)
projects = db.relationship("Project", backref="owner", primaryjoin="users.id == projects.owner_id")
posts = db.relationship("Post", backref="author", primaryjoin="users.id == posts.author_id")
class Project(db.Model):
__tablename__ = "projects"
id = db.Column(db.Integer, primary_key=True)
project_client = db.Column(db.String(60))
word_count = db.Column(db.Integer, nullable=False)
deadline = db.Column(db.DateTime, default=next_week)
completed = db.Column(db.Boolean, default=False)
owner_id = db.Column(db.String, db.ForeignKey("users.id"))
class Post(db.Model):
__tablename__ = "posts"
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(80))
views = db.Column(db.Integer)
author_id = db.Column(db.String, db.ForeignKey("users.id"))

FastAPI GET gives 422 Unprocessable Entity error

I am new using FastAPI python and I am right now just trying to GET all the appointments in the database. The models.py is autogenerated with sqlacodegen. So it is one-to-one with the database and we have connection to the database.
But the problem is that when I try to go to http://127.0.0.1:8000/appointments it gives this data:
{"detail":[{"loc":["query","self"],"msg":"field required","type":"value_error.missing"}]}
and the server gives this "GET /appointments HTTP/1.1" 422 Unprocessable Entity"
but I don't know what is wrong..
in the database the data looks like this: (dummy data)
i have uploaded all my code under here:
Models.py
# coding: utf-8
from sqlalchemy import Column, DateTime, ForeignKey, String, Table
from sqlalchemy.dialects.mysql import INTEGER
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base
from .database import Base
Base = declarative_base()
metadata = Base.metadata
class Customer(Base):
__tablename__ = 'Customer'
CPR = Column(INTEGER(11), primary_key=True)
Name = Column(String(45))
Email = Column(String(45))
PhoneNumber = Column(INTEGER(11))
class Producer(Base):
__tablename__ = 'Producer'
CVR = Column(INTEGER(11), primary_key=True)
Name = Column(String(45))
PhoneNumber = Column(INTEGER(11))
Adress = Column(String(45))
Supplier = relationship('Supplier', secondary='Producer_has_Supplier')
class Statistic(Base):
__tablename__ = 'Statistics'
idStatistics = Column(INTEGER(11), primary_key=True)
CustomerCount = Column(INTEGER(11))
ArtistCustomerCount = Column(INTEGER(11))
SessionCount = Column(INTEGER(11))
AppliedInkColorCount = Column(INTEGER(11))
class Supplier(Base):
__tablename__ = 'Supplier'
CVR = Column(INTEGER(11), primary_key=True)
Name = Column(String(45))
PhoneNumber = Column(String(45))
Adress = Column(String(45))
class Ink(Base):
__tablename__ = 'Ink'
BatchNumber = Column(INTEGER(11), primary_key=True, nullable=False)
Brand = Column(String(45))
ColorCode = Column(String(15))
ExperationDate = Column(DateTime)
Price = Column(INTEGER(11))
Producer_CVR = Column(ForeignKey('Producer.CVR'), primary_key=True, nullable=False, index=True)
Producer = relationship('Producer')
Tattoo = relationship('Tattoo', secondary='Tattoo_has_Ink')
t_Producer_has_Supplier = Table(
'Producer_has_Supplier', metadata,
Column('Producer_CVR', ForeignKey('Producer.CVR'), primary_key=True, nullable=False, index=True),
Column('Supplier_CVR', ForeignKey('Supplier.CVR'), primary_key=True, nullable=False, index=True)
)
class Tattooparlor(Base):
__tablename__ = 'Tattooparlor'
CVR = Column(INTEGER(11), primary_key=True, nullable=False)
Name = Column(String(75))
Adress = Column(String(45))
PhoneNumber = Column(INTEGER(11))
Email = Column(String(45))
Statistics_idStatistics = Column(ForeignKey('Statistics.idStatistics'), primary_key=True, nullable=False, index=True)
Supplier_CVR = Column(ForeignKey('Supplier.CVR'), primary_key=True, nullable=False, index=True)
Statistic = relationship('Statistic')
Supplier = relationship('Supplier')
class Artist(Base):
__tablename__ = 'Artist'
CPR = Column(INTEGER(11), primary_key=True)
Name = Column(String(45))
PhoneNumber = Column(INTEGER(11))
Email = Column(String(45))
Price = Column(INTEGER(11))
Tattooparlor_CVR = Column(ForeignKey('Tattooparlor.CVR'), nullable=False, index=True)
Tattooparlor = relationship('Tattooparlor')
t_Parlor_has_Ink = Table(
'Parlor_has_Ink', metadata,
Column('Ink_batchnumber', ForeignKey('Ink.BatchNumber'), index=True),
Column('Parlor_storageID', ForeignKey('Tattooparlor.CVR'), index=True),
Column('Quantity', INTEGER(11))
)
class Appointment(Base):
__tablename__ = 'Appointment'
id = Column(INTEGER(11), primary_key=True, nullable=False)
DateTime = Column(DateTime)
SessionLenght = Column(INTEGER(11))
Customer_CPR = Column(ForeignKey('Customer.CPR'), primary_key=True, nullable=False, index=True)
Tattooparlor_CVR = Column(ForeignKey('Tattooparlor.CVR'), primary_key=True, nullable=False, index=True)
Artist_CPR = Column(ForeignKey('Artist.CPR'), nullable=False, index=True)
Artist = relationship('Artist')
Customer = relationship('Customer')
Tattooparlor = relationship('Tattooparlor')
class Tattoo(Base):
__tablename__ = 'Tattoo'
idTattoo = Column(INTEGER(11), primary_key=True, nullable=False)
Description = Column(String(200))
PlacementOnBody = Column(String(45))
Appointment_idAppointment = Column(ForeignKey('Appointment.idAppointment'), primary_key=True, nullable=False, index=True)
Appointment = relationship('Appointment')
t_Tattoo_has_Ink = Table(
'Tattoo_has_Ink', metadata,
Column('Tattoo_idTattoo', ForeignKey('Tattoo.idTattoo'), primary_key=True, nullable=False, index=True),
Column('Ink_BatchNumber', ForeignKey('Ink.BatchNumber'), primary_key=True, nullable=False, index=True)
)
Schemas.py
from typing import List
from sqlalchemy.orm import Session
from .models import Appointment
from .schemas import AppointmentBase
# Function to get list of car info
def get_all_apointments(session: Session) -> List[Appointment]:
print(List[Appointment])
return session.query(Appointment).all()
crud.py
from typing import List, Optional
from pydantic import BaseModel
import datetime
# TO support creation and update APIs
class AppointmentBase(BaseModel):
DateTime = str(datetime)
SessionLenght = int
# TO support list and get APIs
class Appointment(AppointmentBase):
Appointment_id = int
Customer_CPR = int
Tattooparlor_CVR =int
Artist_CPR = int
class Config:
orm_mode = True
arbitrary_types_allowed = True
# To support list API
class PaginatedAppointmentInfo(BaseModel):
data: List[Appointment] = []
class Config:
orm_mode = True
arbitrary_types_allowed = True
main.py
from fastapi import Depends, FastAPI, HTTPException
from sqlalchemy.orm import Session
from pydantic import BaseModel
import uvicorn
from . import models
from .database import SessionLocal, engine
from .schemas import Appointment, AppointmentBase, PaginatedAppointmentInfo
from .crud import get_all_apointments
# Initialize the app
app = FastAPI()
models.Base.metadata.create_all(bind=engine)
app = FastAPI()
# Dependency
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
# API to get the list of car info
#app.get("/appointments", response_model=PaginatedAppointmentInfo)
def list_apointments(self):
apointments_list = get_all_apointments(self.session)
response = {"data": apointments_list}
return response
# GET operation at route '/'
#app.get('/')
def root_api():
return {"message": "Welcome to Balasundar's Technical Blog"}
The error message is telling you that you have defined a required query argument named self that isn't being submitted:
{"detail":[{"loc":["query","self"],"msg":"field required"
^ ^
type name
If you look at the function you're calling, you'll see that you have a definition that mentions that specific name:
# API to get the list of car info
#app.get("/appointments", response_model=PaginatedAppointmentInfo)
def list_apointments(self):
^
Since there is no implicit first argument for regular functions (only for methods inside a class), FastAPI expects a self argument to be supplied to the function. Since you're not including that - I'm guessing you have extracted this from a class, since you're also using self.session further down - FastAPI gives an error.
As you have defined a get_db dependency to get the session, you should probably use that instead (since self outside of a class context doesn't have any particular meaning):
# API to get the list of car info
#app.get("/appointments", response_model=PaginatedAppointmentInfo)
def list_apointments(session = Depends(get_db)):
apointments_list = get_all_apointments(session)
response = {"data": apointments_list}
return response
There is no longer any required arguments for the function - the session gets retrieved from get_db and there are no other arguments to the function.

Neither SQLALCHEMY_DATABASE_URI nor SQLALCHEMY_BINDS

I am trying to create an API in Python that uses a Postgresql database. I am attempting a simple endpoint to pull to check to see if the database can connect and pull data. I am probably missing something simple and need someone to point it out. Below is my main.py file
import psycopg2
import model
import os
from flask import Flask, jsonify, request
from flask_sqlalchemy import SQLAlchemy
uname = os.environ['uname']
pas = os.environ['pas']
url = os.environ['url']
port = os.environ['port']
dbase = os.environ['dbase']
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql+psycopg2://' + uname + ':' + pas + '#' + url + ':' + port + '/' + dbase
db = SQLAlchemy(app)
#app.route('/test')
def test():
tst = model.Doc.query.filter_by(doc_num=1).first()
return jsonify(tst)
if __name__ == '__main__':
app.run()
I also have a model.py file where my database is modeled out.
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import Column, Integer, String, Date, ForeignKey
from flask_marshmallow import Marshmallow
app = Flask(__name__)
db = SQLAlchemy(app)
ma = Marshmallow(app)
class Aud(db.Model):
__tablename__ = 'aud'
__table_args__ = {'schema': 'cirsx'}
aud_num = Column(Integer, primary_key=True)
aud_name = Column(String, nullable=False, unique=True)
aud_desc = Column(String)
class AudSchema(ma.Schema):
class Meta:
fields = ('aud_num', 'aud_name', 'aud_desc')
class DocTyp(db.Model):
__tablename__ = 'doctyp'
__table_args__ = {'schema': 'cirsx'}
doctyp_num = Column(Integer, primary_key=True)
doctyp_name = Column(String, nullable=False, unique=True)
doctyp_desc = Column(String)
class DocTypSchema(ma.Schema):
class Meta:
fields = ('doctyp_num', 'doctyp_name', 'doctyp_desc')
class Doc(db.Model):
__tablename__ = 'doc'
__table_args__ = {'schema': 'cirsx'}
doc_num = Column(Integer, primary_key=True)
doctyp_num = Column(Integer, ForeignKey('doctyp_num'))
aud_num = Column(Integer, ForeignKey('aud_num'))
doc_path = Column(String, nullable=False)
title = Column(String, nullable=False)
author = Column(String)
keywords = Column(String)
pub_dt = Column(Date)
doc_abs = Column(String)
doc_txt = Column(String)
class DocSchema(ma.Schema):
class Meta:
fields = ('doc_num',
'doctyp_num',
'aud_num',
'doc_path',
'title',
'author',
'keywords',
'pub_dt',
'doc_abs',
'doc_txt')
aud_schema = AudSchema()
aud_schemas = AudSchema(many=True)
doctyp_schema = DocTypSchema()
doctyp_schemas = DocTypSchema(many=True)
doc_schema = DocSchema()
doc_schemas = DocSchema(many=True)
if __name__ == '__main__':
app.run()
Is there something that I am missing to why I am getting this error?

Flask/SQLAlchemy - error creating models with one to many relationship (One or more mappers failed to initialize...)

I am trying to make one to many relationship between these 2 tables ("users" and "planets") but am getting this error:
One or more mappers failed to initialize - can't proceed with initialization of other mappers. Triggering mapper: 'mapped class User->users'. Original exception was: Could not determine join condition between parent/child tables on relationship User.planet - there are no foreign keys linking these tables. Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint, or specify a 'primaryjoin' expression.
I have seen answers to this question but none of them worked, I don't know where is the problem?
I also want to separate the 2 models in 2 different files, how that gonna work in this case?
Thanks so much for your help.
from sqlalchemy import Column, Integer, String, FLOAT
from app import db, ma
# database models:
class User(db.Model):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
first_name = Column(String)
last_name = Column(String)
email = Column(String, unique=True)
password = Column(String)
planet = db.relationship('Planet', backref='users', lazy='dynamic')
class Planet(db.Model):
__tablename__ = 'planets'
planet_id = Column(Integer, primary_key=True)
planet_name = Column(String)
planet_type = Column(String)
home_star = Column(String)
mass = Column(FLOAT)
radius = Column(FLOAT)
distance = Column(FLOAT)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
class UserSchema(ma.Schema):
class Meta:
fields = ('id', 'first_name', 'last_name', 'email', 'password')
class PlanetSchema(ma.Schema):
class Meta:
fields = ('planet_id', 'planet_name', 'planet_type', 'home_star', 'mass', 'radius', 'distance')
#__init__.py
from flask import Flask, jsonify, request
from flask_sqlalchemy import SQLAlchemy
import os
from flask_marshmallow import Marshmallow
from flask_jwt_extended import JWTManager, jwt_required, create_access_token
# from flask_cors import CORS, cross_origin
db = SQLAlchemy()
ma = Marshmallow()
jwt = JWTManager()
def create_app():
app = Flask(__name__)
basedir = os.path.abspath(os.path.dirname(__file__))
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'planets.db')
app.config['JWT_SECRET_KEY']='super_secret'
# cors = CORS(app)
# app.config['CORS_HEADERS'] = 'Content-Type'
db.init_app(app)
ma.init_app(app)
jwt.init_app(app)
# jwt = JWTManager(app)
from views import planet, users
app.register_blueprint(planet.main)
app.register_blueprint(users.users)
return app

Cannot create user in database: sqlalchemy.exc.InvalidRequestError

I am trying to add an user to the database file but i get the following error when trying to create an User object:
sqlalchemy.exc.InvalidRequestError: One or more mappers failed to initialize - can't proceed with initialization of other mappers. Triggering mapper: 'mapped class Patient->patient'. Original exception was: Could not determine join condition between parent/child tables on relationship Patient.documents - there are no foreign keys linking these tables. Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint, or specify a 'primaryjoin' expression.
from flask import Flask, render_template, flash
from flask_sqlalchemy import SQLAlchemy
from forms import LoginForm
app = Flask(__name__)
app.config['SECRET_KEY'] = 'SECRETKEY'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///storage.db'
db = SQLAlchemy(app)
"""
Users
"""
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
username = db.Column(db.String, unique=True, nullable=False)
password = db.Column(db.String, nullable=False)
mail = db.Column(db.String, default='test#mail')
role = db.Column(db.Integer)
def __repr__(self):
return f"User('{self.username}', '{self.name}')"
"""
Patients
"""
class Patient(db.Model):
id = db.Column(db.Integer, primary_key=True)
prename = db.Column(db.String, nullable=False)
name = db.Column(db.String, nullable=False)
mail = db.Column(db.String, default='test#mail')
birthdate = db.Column(db.String, nullable=False)
documents = db.relationship('Doc', backref='patient', lazy=True)
def __repr__(self):
return f"Patient('{self.prename}', '{self.name}')"
"""
Documents
"""
class Doc(db.Model):
from datetime import datetime
pdfid = db.Column(db.Integer, primary_key=True)
path = db.Column(db.String)
created = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
deletetime = db.Column(db.Integer, nullable=False)
patientid = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
def __repr__(self):
return f"Docs('{self.path}', '{self.created}')"
My Steps in a python Terminal (the file is called index):
from index import db
db.create_all()
from index import User, Doc, Patient
user1 = User(name='Test User', username='test', password='testtest', role=1)
When I try step 4 I get the above described error.
I don't see any problem in my code so I would appreciate any help :)

Categories

Resources