sqlalchemy.exc.NoReferencedTableError: Foreign key could not find table - python

I have some models that i'd like to migrate, 2 of them are:
FamilyMember.py
class FamilyMember(db.Model):
__tablename__ = 'family_members'
id = db.Column(db.Integer, primary_key=True)
parent_id = db.Column(db.Integer, db.ForeignKey('users.id'))
name = db.Column(db.String(120), index=True)
email = db.Column(db.String(120), index=True, unique=True)
password = db.Column(db.String(128), nullable=False)
notification = db.Column(db.Boolean, default=True)
auto_ml = db.Column(db.Boolean, default=True)
photo = db.Column(db.String(128), nullable=True)
created_at = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
updated_at = db.Column(db.DateTime(timezone=True), server_default=db.func.now(), onupdate=db.func.now())
notifications = db.relationship('Notification', backref='family_members', lazy='dynamic')
And Notification.py
class Notification(db.Model):
__tablename__ = 'notifications'
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
fm_id = db.Column(db.Integer, db.ForeignKey('family_members.id'))
text = db.Column(db.String(255))
read = db.Column(db.Boolean, default=False)
type = db.Column(db.Integer)
created_at = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
updated_at = db.Column(db.DateTime(timezone=True), server_default=db.func.now(), onupdate=db.func.now())
Regarding to this post, i have to explicitly state table name with __tablename__ = 'tablename', i've done that but it didn't work the way it supposed to and still got the error sqlalchemy.exc.NoReferencedTableError: Foreign key associated with column 'notifications.fm_id' could not find table 'family_members' with which to generate a foreign key to target column 'id'. What should i do?

You can use back_populates instead of backref in db.relationship()
class Notification(db.Model):
__tablename__ = 'notifications'
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
fm_id = db.Column(db.Integer, db.ForeignKey('family_members.id'))
text = db.Column(db.String(255))
read = db.Column(db.Boolean, default=False)
type = db.Column(db.Integer)
created_at = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
updated_at = db.Column(db.DateTime(timezone=True), server_default=db.func.now(), onupdate=db.func.now())
family_members = db.relationship("FamilyMember", back_populates="notifications")
class FamilyMember(db.Model):
__tablename__ = 'family_members'
id = db.Column(db.Integer, primary_key=True)
parent_id = db.Column(db.Integer, db.ForeignKey('users.id'))
name = db.Column(db.String(120), index=True)
email = db.Column(db.String(120), index=True, unique=True)
password = db.Column(db.String(128), nullable=False)
notification = db.Column(db.Boolean, default=True)
auto_ml = db.Column(db.Boolean, default=True)
photo = db.Column(db.String(128), nullable=True)
created_at = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
updated_at = db.Column(db.DateTime(timezone=True), server_default=db.func.now(), onupdate=db.func.now())
notifications = db.relationship("Notification", back_populates="family_member")

Related

sqlalchemy.exc.InvalidRequestError: When initializing mapper mapped class Order->order, expression 'Status' failed to locate a name ('Status')

Cannot save record to my db.
I created endpoint which makes user and saves him to db:
#router.post("/user/register/", tags=['user'], status_code=201)
async def user_register_web(user: RegisterWebSchema, db: Session = Depends(get_db)):
if user.password != user.password_repeat:
raise HTTPException(status_code=404, detail="Passwords dont match each other!")
db_user = UserModel(name=user.name.title(), surname=user.surname.title(), email=user.email,
phone_number=user.phone_number, login=user.login, password=user.password,
photo=None, is_admin=False, coins=0)
db.add(db_user)
db.commit()
db.refresh(db_user)
return {"JWT Token": signJWT(user.email),
**user.dict()}
Here is model of my User:
class User(Base):
__tablename__ = "user"
__table_args__ = {'extend_existing': True}
id = Column(Integer, primary_key=True, index=True)
name = Column(String(50), nullable=False)
surname = Column(String(50), nullable=False)
email = Column(String(50), unique=True, nullable=False)
phone_number = Column(String(15), unique=True, nullable=False)
login = Column(String(50), unique=True, nullable=False)
password = Column(String(80), nullable=False)
photo = Column(String(80), nullable=True)
is_admin = Column(Boolean, nullable=False)
coins = Column(Integer, nullable=False)
time_created = Column(DateTime(timezone=True), server_default=func.now())
time_updated = Column(DateTime(timezone=True), onupdate=func.now())
address_id = Column(Integer, ForeignKey("address.id"), nullable=False)
address = relationship("Address", back_populates="user")
pin = relationship("Pin", back_populates="user")
payment_card = relationship("PaymentCard", back_populates="user")
order = relationship("Order", back_populates="user")
feedback = relationship("Feedback", back_populates="user")
post = relationship("Post", back_populates="user")
comment = relationship("Comment", back_populates="user")
animal = relationship("Animal", back_populates="user")
walk = relationship("Walk", back_populates="user")
and here is the error I get:
sqlalchemy.exc.InvalidRequestError: When initializing mapper mapped class Order->order, expression 'Status' failed to locate a name ('Status'). If this is a class name, consider adding this relationship() to the <class 'database.models.OrderModel.Order'> class after both dependent classes have been defined.
model of Order:
class Order(Base):
__tablename__ = "order"
__table_args__ = {'extend_existing': True}
id = Column(Integer, primary_key=True, index=True)
order_code = Column(String(15), nullable=True)
time_created = Column(DateTime(timezone=True), server_default=func.now())
time_updated = Column(DateTime(timezone=True), onupdate=func.now())
status_id = Column(Integer, ForeignKey("status.id"), nullable=False)
status = relationship("Status", back_populates="order")
payment_method_id = Column(Integer, ForeignKey("payment_method.id"), nullable=False)
payment_method = relationship("PaymentMethod", back_populates="order")
user_id = Column(Integer, ForeignKey("user.id"), nullable=False)
user = relationship("User", back_populates="order")
post_office = relationship("PostOffice", back_populates="order")
product = relationship("Product", secondary=OrderProduct, back_populates="order")
and model of Status:
class Status(Base):
__tablename__ = "status"
id = Column(Integer, primary_key=True, index=True)
name = Column(String(100), nullable=False)
time_created = Column(DateTime(timezone=True), server_default=func.now())
time_updated = Column(DateTime(timezone=True), onupdate=func.now())
order = relationship("Order", back_populates="status")
I createrd migration successfully and then db. I dont understand why it shows lack of relationship, which i created. And it appears in lines of codes which dont even use these Tables.
In order to make it work I had to import all of my modules into api file with endpoint. I don't know why but it works right now.

SQLAlchemy retriving a specific value and convert to an INT

I am trying to get the price value from my EVENTS class as an INT so that I can use it to make a booking by multiplying by the number of attendees for an event when I insert a new row in the booking table.
Tables in databse
class Event(db.Model):
__tablename__ = 'events'
id = db.Column(db.Integer, primary_key=True)
host = db.Column(db.String(80), nullable=False)
event_title = db.Column(db.String(80), nullable=False)
event_description = db.Column(db.String(80), nullable=False)
movie_name = db.Column(db.String(80), nullable=False)
movie_description = db.Column(db.String(80), nullable=False)
genre = db.Column(db.String(80), nullable=False)
movie_start_time = db.Column(db.Time(), nullable=False)
movie_end_time = db.Column(db.Time(), nullable=False)
classification = db.Column(db.String(80), nullable=False)
rating = db.Column(db.Integer(), nullable=False)
actors = db.Column(db.String(200), nullable=False)
directors = db.Column(db.String(200), nullable=False)
event_date = db.Column(db.Date(), nullable=False)
published_date = db.Column(db.Date(), nullable=False)
published_by = db.Column(db.String(80), nullable=False)
image = db.Column(db.String(60), nullable=False)
capacity = db.Column(db.Integer(), nullable=False)
address = db.Column(db.String(80), nullable=False)
status = db.Column(db.String(80), nullable=False)
price = db.Column(db.Integer(), nullable=False)
# ... Create the Comments db.relationship
# relation to call destination.comments and comment.destination
comments = db.relationship('Comment', backref='event')
class Booking(db.Model):
__tablename__ = 'bookings'
id = db.Column(db.Integer, primary_key=True, unique=True)
attendees = db.Column(db.Integer(), nullable=False)
total_price = db.Column(db.Integer(), nullable=False)
booked_at = db.Column(db.DateTime, default=datetime.now())
# foreign key
user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
event_id = db.Column(db.Integer, db.ForeignKey('events.id'))
Code calling from Events table to get price and insert new row into Booking table
price = Event.query.with_entities(Event.price).filter_by(id = event)
user_name = User.query.with_entities(User.id).filter_by(name = current_user.name)
num_attendees = forms.attendees.data
print(num_attendees)
print(type(price))
booking = Booking(attendees=forms.attendees.data,
total_price= price * num_attendees,
user_id = user_name,
event_id = event)
#here the back-referencing works - comment.destination is set
# and the link is created
db.session.add(booking)
db.session.commit()
But I keep running into errors such as TypeError: unsupported operand type(s) for *: 'Row' and 'int'
Thank you

Flask database realtionship issue

I have the following database model:
#login_manager.user_loader
def load_user(id):
return User.query.get(int(id))
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key = True)
username = db.Column(db.String(20), unique=True, nullable=False)
password = db.Column(db.String(30), nullable=False)
email = db.Column(db.String(100), nullable=False, unique=True)
adverts = db.relationship('Advert', backref='autor', lazy=True)
messages_sent = db.relationship('Message',foreign_keys='Message.sender_id', backref='author', lazy='dynamic')
messages_received = db.relationship('Message',foreign_keys='Message.recipient_id', backref='recipient', lazy='dynamic')
telephone = db.Column(db.String(15))
def __repr__(self):
return f"User('{self.username}', '{self.email}'"
class Advert(db.Model):
id = db.Column(db.Integer, primary_key=True)
date = db.Column(db.DateTime, nullable=False, default = datetime.utcnow)
title = db.Column(db.String(100), nullable=False)
content = db.Column(db.Text, nullable = False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
category = db.Column(db.String(50), nullable=False)
price = db.Column(db.Integer)
city = db.Column(db.String(), nullable=False)
messages = db.relationship('Message', backref='messages', lazy=True)
def __repr__(self):
return f"Advert('{self.title}', '{self.date}', '{self.category}')"
class Message(db.Model):
id = db.Column(db.Integer, primary_key=True)
sender_id = db.Column(db.Integer, db.ForeignKey('user.id'))
recipient_id = db.Column(db.Integer, db.ForeignKey('user.id'))
title = db.Column(db.String(100), nullable=False)
body = db.Column(db.String(300), nullable=False)
timestamp = db.Column(db.DateTime, default=datetime.utcnow)
ad_title = db.relationship('Advert', foreign_keys='Advert.title', backref='adtitle', lazy='dynamic')
def __repr__(self):
return f"Message('{self.body}')"
but the relationship between Message and Advert tables doesn't work. I want to do that the every Message have refer to Advert title. Anyone know the solution for this problem?

sqlalchemt---SAWarning: fully NULL primary key identity cannot load any object

model:
'''任务工单'''
__tablename__ = 'task'
id = db.Column(db.Integer, primary_key=True, nullable=False, autoincrement=True)
user_id = db.Column(db.Integer, index=True, nullable=False)
dep_id = db.Column(db.Integer, index=True, nullable=False)
title = db.Column(db.String(200), nullable=False, index=True)
content = db.Column(db.Text, nullable=False)
cate = db.Column(db.SmallInteger, default=1,`enter code here`)
add_time = db.Column(db.Integer, default=int(time.time()), comment="添加时间")
is_top = db.Column(db.SmallInteger, default=0, comment="是否加急 1--加急 0--不加急")
desgin_id = db.Column(db.Integer,comment="设计人员的id")
update_time = db.Column(db.Integer, comment="修改时间")
review_time = db.Column(db.Integer, comment="审核时间")
assignment_time = db.Column(db.Integer, comment='分配时间')
fiannce_time = db.Column(db.Integer, comment='完成时间')
invalid_time = db.Column(db.Integer, comment='无效时间')
desgin_time = db.Column(db.Integer, comment="开始设计时间")
state = db.Column(db.SmallInteger, default=1, comment="状态:1--初始化待分配 2--带设计 3--设计中 4--提交待审核(审核中) 5--驳回 7--完成 0--无效")
use:
taskDicts = Task.query.filter_by(state=state).order_by(desc(Task.is_top),asc(Task.add_time)).offset(offset).limit(10).all()
venv/lib/python3.7/site-packages/sqlalchemy/orm/loading.py:246:
SAWarning: fully NULL primary key identity cannot load any object.
This condition may raise an error in a future release.

Why am I getting InstrumentedAttribute instead of basequery

I have created two models in flask using flask_sqlalchemy as follows:
class Analytics(db.Model, IdMixin, ModelMixin):
__tablename__ = "analytics"
record_id = Column(Integer, ForeignKey("record.id"), nullable=True)
created_at = Column(TIMESTAMP, nullable=True)
updated_at = Column(TIMESTAMP, nullable=True)
class HitLog(db.Model, IdMixin, TimestampMixin, ModelMixin):
__tablename__ = "hit_logs"
record_id = Column(Integer, ForeignKey("record.id"), nullable=True)
url = Column(Text, nullable=False, default='')
ip = Column(String(100), nullable=False, default='0.0.0.0', index=True)
referer = Column(Text, nullable=False, default='')
source = Column(String(255), nullable=False, default='', index=True)
query = Column(Text, nullable=False, default='')
user_agent = Column(String(255), nullable=False, default='')
created_at = Column(TIMESTAMP, nullable=True, index=True)
updated_at = Column(TIMESTAMP, nullable=True, index=True)
deleted_at = Column(TIMESTAMP, nullable=True, index=True)
Both the models are created the same way but still when I check for type, I get different results:
print type(Analytics.query)
print type(HitLog.query)
Gives me:
<class 'flask_sqlalchemy.BaseQuery'>
<class 'sqlalchemy.orm.attributes.InstrumentedAttribute'>
Why is it so?
You have a column named query in HitLog.

Categories