Skip to content

Commit

Permalink
feat(optimize): update settings
Browse files Browse the repository at this point in the history
  • Loading branch information
wangxin688 committed Jan 20, 2024
1 parent e000fd2 commit 36729d3
Show file tree
Hide file tree
Showing 19 changed files with 275 additions and 176 deletions.
6 changes: 0 additions & 6 deletions .env_docker_example

This file was deleted.

8 changes: 8 additions & 0 deletions .env_example
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,11 @@ SQLALCHEMY_DATABASE_URI=postgresql+asyncpg://demo:91fb8e9e009f5b9ce1854d947e6fe4
REDIS_DSN=redis://:cfe1c2c4703abb205d71abdc07cc3f3d@localhost:6379

APP_ENV=PRD

# docker compose
DEFAULT_DB_PASSWORD=91fb8e9e009f5b9ce1854d947e6fe4a3
DEFAULT_DB_USER=demo
DEFAULT_DB_NAME=demo
DEFAULT_DB_PORT=5432

REDIS_DEFAULT_PASS=cfe1c2c4703abb205d71abdc07cc3f3d
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -159,3 +159,4 @@ cython_debug/
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
.idea/
data
23 changes: 6 additions & 17 deletions alembic.ini
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@ script_location = alembic
# Uncomment the line below if you want the files to be prepended with date and time
# see https://alembic.sqlalchemy.org/en/latest/tutorial.html#editing-the-ini-file
# for all available tokens
# file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s
file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s

# sys.path path, will be prepended to sys.path if present.
# defaults to the current working directory.
prepend_sys_path = .

# timezone to use when rendering the date within the migration file
# as well as the filename.
# If specified, requires the python>=3.9 or backports.zoneinfo library.
# Any required deps can installed by adding `alembic[tz]` to the pip requirements
# string value is passed to ZoneInfo()
# If specified, requires the python-dateutil library that can be
# installed by adding `alembic[tz]` to the pip requirements
# string value is passed to dateutil.tz.gettz()
# leave blank for localtime
# timezone =

Expand All @@ -36,10 +36,10 @@ prepend_sys_path = .
# sourceless = false

# version location specification; This defaults
# to alembic/versions. When using multiple version
# to migrations/versions. When using multiple version
# directories, initial revisions must be specified with --version-path.
# The path separator used here should be the separator specified by "version_path_separator" below.
# version_locations = %(here)s/bar:%(here)s/bat:alembic/versions
# version_locations = %(here)s/bar:%(here)s/bat:migrations/versions

# version path separator; As mentioned above, this is the character used to split
# version_locations. The default within new alembic.ini files is "os", which uses os.pathsep.
Expand All @@ -51,11 +51,6 @@ prepend_sys_path = .
# version_path_separator = space
version_path_separator = os # Use os.pathsep. Default configuration used for new projects.

# set to 'true' to search source files recursively
# in each "version_locations" directory
# new in Alembic version 1.10
# recursive_version_locations = false

# the output encoding used when revision files
# are written from script.py.mako
# output_encoding = utf-8
Expand All @@ -74,12 +69,6 @@ sqlalchemy.url = driver://user:pass@localhost/dbname
# black.entrypoint = black
# black.options = -l 79 REVISION_SCRIPT_FILENAME

# lint with attempts to fix using "ruff" - use the exec runner, execute a binary
# hooks = ruff
# ruff.type = exec
# ruff.executable = %(here)s/.venv/bin/ruff
# ruff.options = --fix REVISION_SCRIPT_FILENAME

# Logging configuration
[loggers]
keys = root,sqlalchemy,alembic
Expand Down
61 changes: 37 additions & 24 deletions alembic/env.py
Original file line number Diff line number Diff line change
@@ -1,77 +1,90 @@
from logging.config import fileConfig

from alembic import context
from sqlalchemy import engine_from_config
from sqlalchemy import pool
from sqlalchemy import pool, Connection
from sqlalchemy.ext.asyncio import AsyncEngine
import asyncio
from src import config as app_config
from alembic import context

from src.db import Base # noqa: F401

# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config = context.config

# Interpret the config file for Python logging.
# This line sets up loggers basically.
if config.config_file_name is not None:
fileConfig(config.config_file_name)
fileConfig(config.config_file_name) # PGH003

# add your model's MetaData object here
# for 'autogenerate' support
# from myapp import mymodel
# target_metadata = mymodel.Base.metadata
target_metadata = None
from src.db import Base # noqa: E402

target_metadata = Base.metadata

# other values from the config, defined by the needs of env.py,
# can be acquired:
# my_important_option = config.get_main_option("my_important_option")
# ... etc.


def get_database_uri() -> str:
return app_config.settings.SQLALCHEMY_DATABASE_URI


def run_migrations_offline() -> None:
"""Run migrations in 'offline' mode.
This configures the context with just a URL
and not an Engine, though an Engine is acceptable
here as well. By skipping the Engine creation
we don't even need a DBAPI to be available.
Calls to context.execute() here emit the given string to the
script output.
"""
url = config.get_main_option("sqlalchemy.url")
url = get_database_uri()
context.configure(
url=url,
target_metadata=target_metadata,
literal_binds=True,
dialect_opts={"paramstyle": "named"},
compare_type=True,
compare_server_default=True,
)

with context.begin_transaction():
context.run_migrations()


def run_migrations_online() -> None:
"""Run migrations in 'online' mode.
def do_run_migrations(connection: Connection) -> None:
context.configure(connection=connection, target_metadata=target_metadata, compare_type=True)

with context.begin_transaction():
context.run_migrations()


async def run_migrations_online() -> None:
"""Run migrations in 'online' mode.
In this scenario we need to create an Engine
and associate a connection with the context.
"""
connectable = engine_from_config(
config.get_section(config.config_ini_section, {}),
prefix="sqlalchemy.",
poolclass=pool.NullPool,
configuration = config.get_section(config.config_ini_section)
assert configuration # noqa: S101
configuration["sqlalchemy.url"] = get_database_uri()
connectable = AsyncEngine(
engine_from_config(
configuration,
prefix="sqlalchemy.",
poolclass=pool.NullPool,
future=True,
)
)

with connectable.connect() as connection:
context.configure(connection=connection, target_metadata=target_metadata)

with context.begin_transaction():
context.run_migrations()
async with connectable.connect() as connection:
await connection.run_sync(do_run_migrations)


if context.is_offline_mode():
run_migrations_offline()
else:
run_migrations_online()
asyncio.run(run_migrations_online())
145 changes: 145 additions & 0 deletions alembic/versions/2024_01_20_1433-a72f51adf94a_init_db.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
"""init db
Revision ID: a72f51adf94a
Revises:
Create Date: 2024-01-20 14:33:41.546660
"""
from collections.abc import Sequence

import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

from alembic import op

# revision identifiers, used by Alembic.
revision: str = "a72f51adf94a"
down_revision: str | None = None
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"menu",
sa.Column("id", sa.Integer(), nullable=False),
sa.Column("name", sa.String(), nullable=False, comment="the unique name of route"),
sa.Column("hidden", sa.Boolean(), server_default=sa.text("false"), nullable=False),
sa.Column("redirect", sa.String(), nullable=False, comment="redirect url for the route"),
sa.Column(
"hideChildrenInMenu",
sa.Boolean(),
server_default=sa.text("false"),
nullable=False,
comment="hide children in menu force or not",
),
sa.Column("order", sa.Integer(), nullable=False),
sa.Column("title", sa.String(), nullable=False, comment="the title of the route, 面包屑"),
sa.Column("icon", sa.String(), nullable=True),
sa.Column(
"keepAlive",
sa.Boolean(),
server_default=sa.text("false"),
nullable=False,
comment="cache route, 开启multi-tab时为true",
),
sa.Column(
"hiddenHeaderContent",
sa.Boolean(),
server_default=sa.text("false"),
nullable=False,
comment="隐藏pageheader页面带的面包屑和标题栏",
),
sa.Column("permission", postgresql.ARRAY(sa.Integer(), dimensions=1), nullable=True),
sa.Column("parent_id", sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(["parent_id"], ["menu.id"], ondelete="CASCADE"),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint("name"),
)
op.create_table(
"permission",
sa.Column("id", sa.UUID(), nullable=False),
sa.Column("name", sa.String(), nullable=False),
sa.Column("url", sa.String(), nullable=False),
sa.Column("method", sa.String(), nullable=False),
sa.Column("tag", sa.String(), nullable=False),
sa.PrimaryKeyConstraint("id"),
)
op.create_table(
"role",
sa.Column("id", sa.Integer(), nullable=False),
sa.Column("name", sa.String(), nullable=False),
sa.Column("slug", sa.String(), nullable=False),
sa.Column("description", sa.String(), nullable=True),
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False),
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False),
sa.PrimaryKeyConstraint("id"),
)
op.create_index(op.f("ix_role_created_at"), "role", ["created_at"], unique=False)
op.create_table(
"group",
sa.Column("id", sa.Integer(), nullable=False),
sa.Column("name", sa.String(), nullable=False),
sa.Column("description", sa.String(), nullable=True),
sa.Column("role_id", sa.Integer(), nullable=False),
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False),
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(["role_id"], ["role.id"], ondelete="CASCADE"),
sa.PrimaryKeyConstraint("id"),
)
op.create_index(op.f("ix_group_created_at"), "group", ["created_at"], unique=False)
op.create_table(
"role_menu",
sa.Column("role_id", sa.Integer(), nullable=False),
sa.Column("menu_id", sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(["menu_id"], ["menu.id"]),
sa.ForeignKeyConstraint(["role_id"], ["role.id"]),
sa.PrimaryKeyConstraint("role_id", "menu_id"),
)
op.create_table(
"role_permission",
sa.Column("role_id", sa.Integer(), nullable=False),
sa.Column("permission_id", sa.UUID(), nullable=False),
sa.ForeignKeyConstraint(["permission_id"], ["permission.id"]),
sa.ForeignKeyConstraint(["role_id"], ["role.id"]),
sa.PrimaryKeyConstraint("role_id", "permission_id"),
)
op.create_table(
"user",
sa.Column("id", sa.Integer(), nullable=False),
sa.Column("name", sa.String(), nullable=False),
sa.Column("email", sa.String(), nullable=True),
sa.Column("phone", sa.String(), nullable=True),
sa.Column("password", sa.String(), nullable=False),
sa.Column("avatar", sa.String(), nullable=True),
sa.Column("last_login", sa.DateTime(timezone=True), nullable=True),
sa.Column("is_active", sa.Boolean(), server_default=sa.text("true"), nullable=False),
sa.Column("group_id", sa.Integer(), nullable=False),
sa.Column("role_id", sa.Integer(), nullable=False),
sa.Column("auth_info", postgresql.JSON(astext_type=sa.Text()), nullable=True),
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False),
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(["group_id"], ["group.id"], ondelete="CASCADE"),
sa.ForeignKeyConstraint(["role_id"], ["role.id"], ondelete="CASCADE"),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint("email"),
sa.UniqueConstraint("phone"),
)
op.create_index(op.f("ix_user_created_at"), "user", ["created_at"], unique=False)
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index(op.f("ix_user_created_at"), table_name="user")
op.drop_table("user")
op.drop_table("role_permission")
op.drop_table("role_menu")
op.drop_index(op.f("ix_group_created_at"), table_name="group")
op.drop_table("group")
op.drop_index(op.f("ix_role_created_at"), table_name="role")
op.drop_table("role")
op.drop_table("permission")
op.drop_table("menu")
# ### end Alembic commands ###
6 changes: 3 additions & 3 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ services:
- ./data/redis:/var/lib/redis
command: redis-server --requirepass ${REDIS_DEFAULT_PASS} # --notify-keyspace-events Ex
env_file:
- .env_docker
- .env
postgres:
image: postgres:latest
ports:
- "{$DEFAULT_DB_PORT}:5432"
- "${DEFAULT_DB_PORT}:5432"
volumes:
- ./data/postgres:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=${DEFAULT_DB_PASSWORD}
- POSTGRES_USER=${DEFAULT_DB_USER}
- POSTGRES_DB=${DEFAULT_DB_NAME}
env_file:
- .env_docker
- .env
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ dependencies = [
"alembic>=1.13.1",
"sqlalchemy>=2.0.25",
"pydantic-settings>=2.1.0",
"pydantic-extra-types>=2.3.0",
"uvicorn[standard]>=0.25.0",
"pyjwt>=2.8.0",
"pandas>=2.1.4",
Expand Down Expand Up @@ -70,6 +69,8 @@ fixable = ["ALL"]
"deps.py" = ["B008"]
"src/internal/api.py" = ["ARG001"]
"src/auth/schemas.py" = ["N815"] # frontend menu
"alembic/*.py" = ["INP001", "UP007"]
"__init__.py" = ["F403"]

[tool.ruff.flake8-bugbear]
extend-immutable-calls=[
Expand Down
Loading

0 comments on commit 36729d3

Please sign in to comment.