Skip to content

Commit

Permalink
Create database models
Browse files Browse the repository at this point in the history
- Add db models
- Add commands to create/drop tables
- Fix pdm serve command
  • Loading branch information
greyli committed Dec 18, 2023
1 parent 791258e commit 9af6431
Show file tree
Hide file tree
Showing 7 changed files with 310 additions and 3 deletions.
2 changes: 0 additions & 2 deletions .flaskenv

This file was deleted.

8 changes: 7 additions & 1 deletion README.md
Expand Up @@ -23,7 +23,13 @@ Run the backend application:
pdm serve
```

Run the frontend development server(need to install [pnpm](https://pnpm.io/)):
You can create tables in the database by running:

```bash
pdm create-tables
```

Run the frontend development server (need to install [pnpm](https://pnpm.io/)):

```bash
cd frontend
Expand Down
2 changes: 2 additions & 0 deletions backend/.flaskenv
@@ -0,0 +1,2 @@
FLASK_DEBUG=1
FLASK_APP=app.py
2 changes: 2 additions & 0 deletions backend/bamboo/__init__.py
Expand Up @@ -6,6 +6,7 @@
from bamboo.views.page import page_bp
from bamboo.views.talk import talk_bp
from bamboo.core.extensions import db, migrate
from bamboo.core.commands import register_commands
from bamboo.settings import config


Expand All @@ -28,4 +29,5 @@ def create_app(config_name: str) -> APIFlask:
db.init_app(app)
migrate.init_app(app, db)

register_commands(app)
return app
16 changes: 16 additions & 0 deletions backend/bamboo/core/commands.py
@@ -0,0 +1,16 @@
import click

from bamboo.core.extensions import db
from bamboo.models import *


def register_commands(app):
@app.cli.command(name='create-tables')
def create_tables():
db.create_all()
click.echo('Tables created')

@app.cli.command(name='drop-tables')
def drop_tables():
db.drop_all()
click.echo('Tables dropped')
281 changes: 281 additions & 0 deletions backend/bamboo/models.py
@@ -0,0 +1,281 @@
from datetime import datetime

from sqlalchemy import Column, Integer, String, Text, ForeignKey, \
Boolean, DateTime, Float
from sqlalchemy.orm import relationship
from werkzeug.security import generate_password_hash, check_password_hash

from bamboo.core.extensions import db


class User(db.Model):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
name = Column(String)
username = Column(String)
password_hash = Column(String)
biology = Column(String)
introduction = Column(String)
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
active = Column(Boolean)
profile_image_id = Column(Integer, ForeignKey('media.id'))
role_id = Column(String, ForeignKey('role.id'))

profile_image = relationship('Media', foreign_keys=[profile_image_id])
role = relationship('Role', back_populates='users')
blogs = relationship('BlogAuthors', back_populates='author')

@property
def password(self):
raise AttributeError('Write-only property!')

@password.setter
def password(self, password):
self.password_hash = generate_password_hash(password)

def validate_password(self, password):
return check_password_hash(self.password_hash, password)


class Role(db.Model):
__tablename__ = 'role'
id = Column(Integer, primary_key=True)
name = Column(String)
permissions = Column(Integer)
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

users = relationship('User', back_populates='role')


class Media(db.Model):
__tablename__ = 'media'
id = Column(Integer, primary_key=True)
path = Column(String)
content_type = Column(String)
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)


class Site(db.Model):
__tablename__ = 'site'
id = Column(Integer, primary_key=True)
config = Column(Text)
template_url = Column(String)
deploy_target = Column(String)
deploy_method = Column(String)
deploy_secret = Column(Text)
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

pages = relationship('Page', back_populates='site')
notifications = relationship('Notification', back_populates='site')
volunteer_forms = relationship('VolunteerForm', back_populates='site')
sponsor_forms = relationship('SponsorForm', back_populates='site')
speaker_forms = relationship('SpeakerForm', back_populates='site')
talks = relationship('Talk', back_populates='site')


class Page(db.Model):
__tablename__ = 'page'
id = Column(Integer, primary_key=True)
title = Column(String)
path = Column(String)
content = Column(Text)
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
site_id = Column(Integer, ForeignKey('site.id'))

site = relationship('Site', back_populates='pages')


class Notification(db.Model):
__tablename__ = 'notification'
id = Column(Integer, primary_key=True)
content = Column(Text)
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
site_id = Column(Integer, ForeignKey('site.id'))

site = relationship('Site', back_populates='notifications')


class VolunteerForm(db.Model):
__tablename__ = 'volunteer_form'
id = Column(Integer, primary_key=True)
# ...
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
site_id = Column(Integer, ForeignKey('site.id'))

site = relationship('Site', back_populates='volunteer_forms')


class SponsorForm(db.Model):
__tablename__ = 'sponsor_form'
id = Column(Integer, primary_key=True)
# ...
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
site_id = Column(Integer, ForeignKey('site.id'))

site = relationship('Site', back_populates='sponsor_forms')


class SpeakerForm(db.Model):
__tablename__ = 'speaker_form'
id = Column(Integer, primary_key=True)
# ...
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
site_id = Column(Integer, ForeignKey('site.id'))

site = relationship('Site', back_populates='speaker_forms')


class Talk(db.Model):
__tablename__ = 'talk'
id = Column(Integer, primary_key=True)
title = Column(String)
content = Column(String)
video_url = Column(String)
slides_url = Column(String)
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
slides_id = Column(Integer, ForeignKey('media.id'))
site_id = Column(Integer, ForeignKey('site.id'))

slides = relationship('Media', foreign_keys=[slides_id])
site = relationship('Site', back_populates='talks')
schedule_items = relationship('ScheduleItem', back_populates='talk')
talk_categories = relationship('TalkCategory', back_populates='talk')


class Category(db.Model):
__tablename__ = 'category'
id = Column(Integer, primary_key=True)
name = Column(String)
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

talk_categories = relationship('TalkCategory', back_populates='category')


class TalkCategory(db.Model):
__tablename__ = 'talk_category'
id = Column(Integer, primary_key=True)
talk_id = Column(Integer, ForeignKey('talk.id'))
category_id = Column(Integer, ForeignKey('category.id'))

talk = relationship('Talk', back_populates='talk_categories')
category = relationship('Category', back_populates='talk_categories')


class Staff(db.Model):
__tablename__ = 'staff'
id = Column(Integer, primary_key=True)
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
city_id = Column(Integer, ForeignKey('city.id'))
staff_id = Column(Integer, ForeignKey('user.id'))

city = relationship('City', back_populates='staffs')
staff = relationship('User', foreign_keys=[staff_id])


class City(db.Model):
__tablename__ = 'city'
id = Column(Integer, primary_key=True)
name = Column(String)
address = Column(String)
latitude = Column(Float)
longitude = Column(Float)
start = Column(DateTime)
end = Column(DateTime)
registration_url = Column(String)
live_urls = Column(String)
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
site_id = Column(Integer, ForeignKey('site.id'))

staffs = relationship('Staff', back_populates='city')
partnerships = relationship('Partership', back_populates='city')
venues = relationship('Venue', back_populates='city')


class Partership(db.Model):
__tablename__ = 'partnership'
id = Column(Integer, primary_key=True)
name = Column(String)
url = Column(String)
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
city_id = Column(Integer, ForeignKey('city.id'))
organization_id = Column(Integer, ForeignKey('organization.id'))

city = relationship('City', back_populates='partnerships')
organization = relationship('Organization', back_populates='partnerships')


class Organization(db.Model):
__tablename__ = 'organization'
id = Column(Integer, primary_key=True)
name = Column(String)
url = Column(String)
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
profile_image_id = Column(Integer, ForeignKey('media.id'))

profile_image = relationship('Media', foreign_keys=[profile_image_id])
partnerships = relationship('Partership', back_populates='organization')


class Blog(db.Model):
__tablename__ = 'blog'
id = Column(Integer, primary_key=True)
title = Column(String)
path = Column(String)
content = Column(Text)
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
site_id = Column(Integer, db.ForeignKey('site.id'))

site = relationship('Site', back_populates='blogs')
authors = relationship('User', back_populates='blogs')


class BlogAuthors(db.Model):
__tablename__ = 'blog_authors'
blog_id = Column(Integer, ForeignKey('blog.id'), primary_key=True)
author_id = Column(Integer, ForeignKey('user.id'), primary_key=True)

blog = relationship('Blog', back_populates='authors')
author = relationship('User', back_populates='blogs')


class ScheduleItem(db.Model):
__tablename__ = 'schedule_item'
id = Column(Integer, primary_key=True)
content = Column(Text)
start = Column(DateTime)
end = Column(DateTime)
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

venue_id = Column(Integer, ForeignKey('venue.id'))
talk_id = Column(Integer, ForeignKey('talk.id'))

venue = relationship('Venue', back_populates='schedule_items')
talk = relationship('Talk', back_populates='schedule_items')


class Venue(db.Model):
id = Column(Integer, primary_key=True)
name = Column(String(30))
address = Column(String(500))
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

city_id = Column(Integer, ForeignKey('city.id'))
city = relationship('City', back_populates='venues')
2 changes: 2 additions & 0 deletions pyproject.toml
Expand Up @@ -20,6 +20,8 @@ package-type = "application"

[tool.pdm.scripts]
serve = { shell = "cd backend && flask run", help = "Run the development server" }
create-tables = { shell = "cd backend && flask create-tables", help = "Create tables" }
drop-tables = { shell = "cd backend && flask drop-tables", help = "Drop tables" }

[tool.pdm.dev-dependencies]
test = [
Expand Down

0 comments on commit 9af6431

Please sign in to comment.