Skip to content

Instantly share code, notes, and snippets.

@TheMuellenator
Forked from angelabauer/main.py
Last active November 20, 2024 16:16
Show Gist options
  • Save TheMuellenator/b4e21f77c04afcac85a7ec2a262ea0d7 to your computer and use it in GitHub Desktop.
Save TheMuellenator/b4e21f77c04afcac85a7ec2a262ea0d7 to your computer and use it in GitHub Desktop.
Day 69 L532 Challenge 1 - Creating Relational Databases (SQL Alchemy 3.1)
## MORE CODE ABOVE
class User(UserMixin, db.Model):
__tablename__ = "users"
id: Mapped[int] = mapped_column(Integer, primary_key=True)
email: Mapped[str] = mapped_column(String(100), unique=True)
password: Mapped[str] = mapped_column(String(100))
name: Mapped[str] = mapped_column(String(100))
#This will act like a List of BlogPost objects attached to each User.
#The "author" refers to the author property in the BlogPost class.
posts = relationship("BlogPost", back_populates="author")
class BlogPost(db.Model):
__tablename__ = "blog_posts"
id: Mapped[int] = mapped_column(Integer, primary_key=True)
# Create Foreign Key, "users.id" the users refers to the tablename of User.
author_id: Mapped[int] = mapped_column(Integer, db.ForeignKey("users.id"))
# Create reference to the User object. The "posts" refers to the posts property in the User class.
author = relationship("User", back_populates="posts")
title: Mapped[str] = mapped_column(String(250), unique=True, nullable=False)
subtitle: Mapped[str] = mapped_column(String(250), nullable=False)
date: Mapped[str] = mapped_column(String(250), nullable=False)
body: Mapped[str] = mapped_column(Text, nullable=False)
img_url: Mapped[str] = mapped_column(String(250), nullable=False)
## MORE CODE BELOW
@CJVdeG
Copy link

CJVdeG commented Jun 23, 2024

I ended up stock on this for some time until I realized clear cache fixes it

@anandachanta19
Copy link

    ``> ![image](https://private-user-images.githubusercontent.com/95513071/307592162-050dee4c-17c4-4d56-b9de-3997eb2f1d5a.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjAzMzU3OTcsIm5iZiI6MTcyMDMzNTQ5NywicGF0aCI6Ii85NTUxMzA3MS8zMDc1OTIxNjItMDUwZGVlNGMtMTdjNC00ZDU2LWI5ZGUtMzk5N2ViMmYxZDVhLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA3MDclMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNzA3VDA2NTgxN1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTkyNWIyY2VlYzYwZTk0NGY3YTY0YjgwODEyZmI0MTA5NTlhMWY4OGVhMjNkMjFjYTRmNjFlMDM5MzgyZmY4MGUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.2s98MkAVyM9iugXjyIxNU-Spzz9hhagOC1hu4UFUHlA) Add the user first then restart server it works for me

Just remove the parameters from Users() and add a method called add_details in User class which assigns value to email, password, name

class User(UserMixin, db.Model):
    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    email: Mapped[str] = mapped_column(String(250), unique=True, nullable=False)
    password: Mapped[str] = mapped_column(String(250), nullable=False)
    name: Mapped[str] = mapped_column(String(250), nullable=False)
    posts = relationship("BlogPost", back_populates="author")

    def add_details(self, email, password, name):
        self.email = email
        self.password = password
        self.name = name
        
    new_user = User()
        new_user.add_details(
            email=form.email.data,
            password=hashed_password,
            name=form.name.data
        )

@n-kar4
Copy link

n-kar4 commented Jul 10, 2024

for 404 I just restarted chrome.

@SuvamTalukder21
Copy link

SuvamTalukder21 commented Jul 18, 2024

class Users(UserMixin, db.Model):
    __tablename__ = "users"

    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    email: Mapped[str] = mapped_column(String(255), unique=True, nullable=False)
    password: Mapped[str] = mapped_column(String(255), nullable=False)
    name: Mapped[str] = mapped_column(String(255), nullable=False)
    posts: Mapped[list[BlogPost]] = relationship("BlogPost", back_populates="author")


class BlogPost(db.Model):
    __tablename__ = "blog_posts"

    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    title: Mapped[str] = mapped_column(String(255), unique=True, nullable=False)
    subtitle: Mapped[str] = mapped_column(String(255), nullable=False)
    date: Mapped[str] = mapped_column(String(255), nullable=False)
    body: Mapped[str] = mapped_column(Text, nullable=False)
    img_url: Mapped[str] = mapped_column(String(255), nullable=False)
    author_id: Mapped[int] = mapped_column(Integer, db.ForeignKey("users.id"))
    author: Mapped[Users] = relationship("Users", back_populates="posts")

This is my piece of code. Please check anyone is it good or not? If anyone wants to modify my code you are free to do that...

@Michael-starz
Copy link

Ok, got it to work.

First comment out the login manager code. We don't have any users in this new database that's why we are getting 404 status code.

# login_manager = LoginManager()
# login_manager.init_app(app)
# @login_manager.user_loader
# def load_user(user_id):
#     return db.get_or_404(Users, user_id)

Next we have to find all the "current_user" code portions in our templates, mostly in index and header html files and comment those out too. e.g.

{# {% if current_user.id == 1 %} #}
      <div class="d-flex justify-content-end mb-4">
        <a
          class="btn btn-primary float-right"
          href="{{url_for('add_new_post')}}"
          >Create New Post</a
        >
      </div>
{# {% endif %} #}

After that create your admin user like before and then uncomment the code :)

Thank you for this man.

@LiviuVpy
Copy link

Has anyone fixed: "AttributeError: 'str' object has no attribute '_sa_instance_state'" , when try to create a new post after the new db comedy?

@MatthewmengBJ
Copy link

@vishalkirtisharma I also got a 404 error coming from here:

# create a user loader callback
@login_manager.user_loader
def load_user(user_id):
    return db.get_or_404(User, user_id)

I solved it by clearing the cache of my browser first. I think it's because the browser remembered who was logged in, but then off course could not find back that user because you had just deleted the .db

Yes, you're right. I opened a 'inplrivate window' and it works fine for me.

@QueenIB
Copy link

QueenIB commented Sep 24, 2024

I ended up stock on this for some time until I realized clear cache fixes it

yeah, clear cache fixed it for me too. thank you.

@northrnrhodes
Copy link

Has anyone fixed: "AttributeError: 'str' object has no attribute '_sa_instance_state'" , when try to create a new post after the new db comedy?

I'm having this same issue. I cannot figure out how to fix it. Currently checking stack overflow for a solution.

@4-l-learning-2-code
Copy link

I get this error

.NoReferencedTableError: Foreign key associated with column 'blog_posts.author_id' could not find table 'users' with which to generate a foreign key to target column 'id'

Here is my code

class User(UserMixin, db.Model):
tablename = "users"
id: Mapped[int] = mapped_column(Integer, primary_key=True)
email: Mapped[str] = mapped_column(String(100), unique= True, nullable=False)
password: Mapped[str] = mapped_column(String(100), nullable=False)
name: Mapped[str] = mapped_column(String(100))
posts: Mapped[list['BlogPost']] = relationship("BlogPost", back_populates="author")

class BlogPost(db.Model):
tablename = "blog_posts"
id: Mapped[int] = mapped_column(Integer, primary_key=True)

author_id: Mapped[int] = mapped_column(Integer, db.ForeignKey("users.id"))
author:Mapped[User] = relationship("Users", back_populates="posts")

title: Mapped[str] = mapped_column(String(250), unique=True, nullable=False)
subtitle: Mapped[str] = mapped_column(String(250), nullable=False)
date: Mapped[str] = mapped_column(String(250), nullable=False)
body: Mapped[str] = mapped_column(Text, nullable=False)
img_url: Mapped[str] = mapped_column(String(250), nullable=False)

@parkook
Copy link

parkook commented Oct 15, 2024

The solution code is no longer working and need Mapped[] for all the lines with the "relationship"

I was getting the following error:

in
class User(UserMixin, db.Model): # parent table
sqlalchemy.exc.ArgumentError: Type annotation for "User.posts" can't be correctly interpreted for Annotated Declarative Table form. ORM annotations should normally make use of the `Mapped[] generic type, or other ORM-compatible generic type, as a container for the actual type, which indicates the intent that the attribute is mapped. Class variables that are not intended to be mapped by the ORM should use ClassVar[]. To allow Annotated Declarative to disregard legacy annotations which don't use Mapped[] to pass, set "allow_unmapped = True" on the class or a superclass this class.

So I had to map the "posts" and "author" that had relationship. Here are these two lines:

In class User(UserMixin, db.Model):

    posts: Mapped[list["BlogPost"]] = relationship("BlogPost", back_populates="author")

In class BlogPost(db.Model):

    author: Mapped["User"] = relationship("User", back_populates="posts")

@parkook
Copy link

parkook commented Oct 15, 2024

Has anyone fixed: "AttributeError: 'str' object has no attribute '_sa_instance_state'" , when try to create a new post after the new db comedy?

I'm having this same issue. I cannot figure out how to fix it. Currently checking stack overflow for a solution.

As we have now added the relationship between tabels, the author is no longer a string but an object.

find the string

current_user.name

replace them with object

current_user

ps. There should be two current_user.name to be replaced.

@by-Soulhunt
Copy link

Ok, got it to work.

First comment out the login manager code. We don't have any users in this new database that's why we are getting 404 status code.

# login_manager = LoginManager()
# login_manager.init_app(app)
# @login_manager.user_loader
# def load_user(user_id):
#     return db.get_or_404(Users, user_id)

Next we have to find all the "current_user" code portions in our templates, mostly in index and header html files and comment those out too. e.g.

{# {% if current_user.id == 1 %} #}
      <div class="d-flex justify-content-end mb-4">
        <a
          class="btn btn-primary float-right"
          href="{{url_for('add_new_post')}}"
          >Create New Post</a
        >
      </div>
{# {% endif %} #}

After that create your admin user like before and then uncomment the code :)

Thx, it works. It takes a lot of time to comment all current_user and other jinja variables, but it done.

@depena89
Copy link

image After days of Troubleshooting this one worked for me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment