New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: create database models #6
Conversation
greyli
commented
Dec 18, 2023
- Add db models
- Add commands to create/drop tables
- Fix pdm serve command
2 questions:
|
Good suggestion! I have to admit I have never writen the 2.0 style model class. I will update it later. Or maybe we could merge this first since it blocks others tasks.
I was try to keep the "views" folder for "view functions", other configuration for the app goes to the "core" folder. @frostming What do you think? |
The module |
.flaskenv
Outdated
@@ -1,2 +0,0 @@ | |||
FLASK_DEBUG=1 | |||
FLASK_APP=backend/app.py |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I didn't notice it is pointing at backend
subfolder, then I prefer to keep it at the top level but fixing the tool.pdm.scripts
instead.
I am confused by this, how can
I agree with this restructure. |
You can create a commands blueprint and set the cli_group argument to None, then you are free to add commands with @commands.cli.command as usual. |
I see, but the naming is not right. They are app-level commands that do not belong to any blueprint. |
It's app level, the key point is cli_group argument, so you can use flask xxx, otherwise you need to use flask commands xxx. |
Any updates on this PR? I am planning to build APIs, but I am blocked because of this. @frostming @greyli |
- Add db models - Add commands to create/drop tables - Fix pdm serve command
Fixed all issues and migrated to SQLAlchemy 2.x code style. @frostming @yuxiaoy1 Please help to review. |
backend/bamboo/models.py
Outdated
|
||
|
||
class User(db.Model): | ||
id: Mapped[int] = mapped_column(Integer, primary_key=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SQLAlchemy 2.x automatically set the data type with type hint, so the declaration can be simplified to id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] username: Mapped[str] ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated.
backend/bamboo/models.py
Outdated
password_hash: Mapped[str] = mapped_column(String) | ||
biology: Mapped[str] = mapped_column(String) | ||
introduction: Mapped[str] = mapped_column(String) | ||
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to https://blog.miguelgrinberg.com/post/it-s-time-for-a-change-datetime-utcnow-is-now-deprecated, it's better to use default=lambda: datetime.now(timezone.utc)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated and used datetime.UTC
to replace timezone.utc
.
backend/bamboo/models.py
Outdated
introduction: Mapped[str] = mapped_column(String) | ||
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow) | ||
updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) | ||
active: Mapped[str] = mapped_column(Boolean) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be Mapped[bool]
, and remove the mapped_column
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
backend/bamboo/core/extensions.py
Outdated
from sqlalchemy.orm import DeclarativeBase | ||
|
||
|
||
class Base(DeclarativeBase): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to be unnecessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's recommended by the Flask-SQLAlchemy docs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, but I have checked there is no difference w/ or w/o it, I think the docs need get updates.
role_id: Mapped[int] = mapped_column(Integer, ForeignKey('role.id')) | ||
|
||
profile_image = relationship('Media', foreign_keys=[profile_image_id]) | ||
role = relationship('Role', back_populates='users') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use WriteOnlyMapped
for relationship: role: WriteOnlyMapped['Role'] = relationship(back_populates='users')
All relationship could be updated as above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated.
backend/bamboo/models.py
Outdated
name: Mapped[str] = mapped_column(String) | ||
username: Mapped[str] = mapped_column(String) | ||
password_hash: Mapped[str] = mapped_column(String) | ||
biology: Mapped[str] = mapped_column(String) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be biography? or just bio.
And this could be null so add optional type hint: bio: Mapped[Optional[str]]
, or it would get not null constraint error using sqlite.
All field optional need updates as above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to bio
and updated optional fields.
@yuxiaoy1 Thank you for the thorough review. I have updated the code based on your suggestions. |
The new code throws: ➜ bamboo git:(db-models) pdm create-tables
Traceback (most recent call last):
File "/home/greyli/bamboo/.venv/bin/flask", line 8, in <module>
sys.exit(main())
^^^^^^
File "/home/greyli/bamboo/.venv/lib/python3.12/site-packages/flask/cli.py", line 1064, in main
cli.main()
File "/home/greyli/bamboo/.venv/lib/python3.12/site-packages/click/core.py", line 1078, in main
rv = self.invoke(ctx)
^^^^^^^^^^^^^^^^
File "/home/greyli/bamboo/.venv/lib/python3.12/site-packages/click/core.py", line 1682, in invoke
cmd_name, cmd, args = self.resolve_command(ctx, args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/greyli/bamboo/.venv/lib/python3.12/site-packages/click/core.py", line 1729, in resolve_command
cmd = self.get_command(ctx, cmd_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/greyli/bamboo/.venv/lib/python3.12/site-packages/flask/cli.py", line 579, in get_command
app = info.load_app()
^^^^^^^^^^^^^^^
File "/home/greyli/bamboo/.venv/lib/python3.12/site-packages/flask/cli.py", line 309, in load_app
app = locate_app(import_name, name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/greyli/bamboo/.venv/lib/python3.12/site-packages/flask/cli.py", line 219, in locate_app
__import__(module_name)
File "/home/greyli/bamboo/backend/app.py", line 8, in <module>
from bamboo import create_app # noqa
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/greyli/bamboo/backend/bamboo/__init__.py", line 9, in <module>
from bamboo.core.commands import register_commands
File "/home/greyli/bamboo/backend/bamboo/core/commands.py", line 4, in <module>
from bamboo.models import *
File "/home/greyli/bamboo/backend/bamboo/models.py", line 12, in <module>
class User(db.Model):
File "/home/greyli/bamboo/backend/bamboo/models.py", line 25, in User
profile_image = WriteOnlyMapped['Media'] = relationship(foreign_keys=[profile_image_id])
~~~~~~~~~~~~~~~^^^^^^^^^
TypeError: 'type' object does not support item assignment I think it's better to move the migration to a separate pull request. Removed the last commit. |
Ok I think we can pull request later. |
backend/bamboo/models.py
Outdated
class Site(db.Model): | ||
__tablename__ = 'site' | ||
id = Column(Integer, primary_key=True) | ||
config = Column(Text) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does sqlite3 support JSON natively? It seems so for the latest versions. And both MySQL and PostgreSQL support JSON. Maybe we can update it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated. SQLite 3.9 and later supports the JSON field.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, just a minor comment and I think we should merge this one to unblock the other tasks.