SCGR commited on
Commit
4117d7e
·
1 Parent(s): e9f41d8

neon setup

Browse files
py_backend/alembic.ini CHANGED
@@ -1,3 +1,3 @@
1
  [alembic]
2
  script_location = alembic
3
- sqlalchemy.url = postgresql://promptaid:promptaid@localhost:5433/promptaid
 
1
  [alembic]
2
  script_location = alembic
3
+ sqlalchemy.url = ${ALEMBIC_DATABASE_URL}
py_backend/alembic/env.py CHANGED
@@ -1,36 +1,67 @@
1
  import os
2
  import sys
3
  from dotenv import load_dotenv
 
 
4
  load_dotenv()
5
 
 
6
  sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
7
 
8
  from alembic import context
9
- from sqlalchemy import engine_from_config, pool
10
  from app.models import Base
11
 
12
- target_metadata = Base.metadata
13
  config = context.config
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
- def run_migrations_offline():
16
- url = config.get_main_option("sqlalchemy.url")
 
 
17
  context.configure(
18
- url=url, target_metadata=target_metadata, literal_binds=True, dialect_opts={"paramstyle": "named"}
 
 
 
 
 
19
  )
20
  with context.begin_transaction():
21
  context.run_migrations()
22
 
23
- def run_migrations_online():
24
- connectable = engine_from_config(
25
- config.get_section(config.config_ini_section),
26
- prefix='sqlalchemy.',
27
- poolclass=pool.NullPool,
28
- )
29
  with connectable.connect() as connection:
30
- context.configure(connection=connection, target_metadata=target_metadata)
 
 
 
 
 
31
  with context.begin_transaction():
32
  context.run_migrations()
33
 
 
34
  if context.is_offline_mode():
35
  run_migrations_offline()
36
  else:
 
1
  import os
2
  import sys
3
  from dotenv import load_dotenv
4
+
5
+ # Load local .env when running migrations locally
6
  load_dotenv()
7
 
8
+ # Allow "from app import ..." imports
9
  sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
10
 
11
  from alembic import context
12
+ from sqlalchemy import create_engine, pool
13
  from app.models import Base
14
 
 
15
  config = context.config
16
+ target_metadata = Base.metadata
17
+
18
+
19
+ def _get_db_url() -> str:
20
+ """
21
+ Prefer a dedicated migration URL; otherwise use the app URL.
22
+ Only adds sslmode=require for remote connections (not localhost).
23
+ """
24
+ url = os.getenv("ALEMBIC_DATABASE_URL") or os.getenv("DATABASE_URL")
25
+ if not url:
26
+ raise RuntimeError("Set ALEMBIC_DATABASE_URL or DATABASE_URL for Alembic migrations.")
27
+
28
+ # Only add sslmode=require for remote connections, not localhost
29
+ if "sslmode=" not in url and "localhost" not in url and "127.0.0.1" not in url:
30
+ url = f"{url}{'&' if '?' in url else '?'}sslmode=require"
31
+ return url
32
 
33
+
34
+ def run_migrations_offline() -> None:
35
+ """Run migrations in 'offline' mode."""
36
+ url = _get_db_url()
37
  context.configure(
38
+ url=url,
39
+ target_metadata=target_metadata,
40
+ literal_binds=True,
41
+ dialect_opts={"paramstyle": "named"},
42
+ compare_type=True,
43
+ compare_server_default=True,
44
  )
45
  with context.begin_transaction():
46
  context.run_migrations()
47
 
48
+
49
+ def run_migrations_online() -> None:
50
+ """Run migrations in 'online' mode."""
51
+ url = _get_db_url()
52
+ connectable = create_engine(url, poolclass=pool.NullPool, future=True)
53
+
54
  with connectable.connect() as connection:
55
+ context.configure(
56
+ connection=connection,
57
+ target_metadata=target_metadata,
58
+ compare_type=True,
59
+ compare_server_default=True,
60
+ )
61
  with context.begin_transaction():
62
  context.run_migrations()
63
 
64
+
65
  if context.is_offline_mode():
66
  run_migrations_offline()
67
  else:
py_backend/app/config.py CHANGED
@@ -17,5 +17,7 @@ class Settings(BaseSettings):
17
  class Config:
18
  env_file = ".env"
19
  env_file_encoding = "utf-8-sig"
 
 
20
 
21
  settings = Settings()
 
17
  class Config:
18
  env_file = ".env"
19
  env_file_encoding = "utf-8-sig"
20
+ extra = "ignore"
21
+ case_sensitive = False
22
 
23
  settings = Settings()
py_backend/app/database.py CHANGED
@@ -1,27 +1,35 @@
1
  import os
2
  import logging
3
-
4
  from sqlalchemy import create_engine
5
  from sqlalchemy.orm import sessionmaker, declarative_base
 
 
6
 
7
  from .config import settings
8
 
9
  raw_db_url = settings.DATABASE_URL
10
- clean_db_url = raw_db_url.split("?", 1)[0]
11
- print(f"database: {clean_db_url.split('@')[-1].split('/')[-1]}")
 
 
 
 
 
12
 
13
  engine = create_engine(
14
- clean_db_url,
15
- echo=True,
16
- future=True,
17
  pool_pre_ping=True,
 
 
 
 
18
  )
19
 
20
  SessionLocal = sessionmaker(
21
  autocommit=False,
22
  autoflush=False,
23
  bind=engine,
24
- future=True
25
  )
26
 
27
  Base = declarative_base()
 
1
  import os
2
  import logging
 
3
  from sqlalchemy import create_engine
4
  from sqlalchemy.orm import sessionmaker, declarative_base
5
+ from sqlalchemy.engine import make_url
6
+ # from sqlalchemy.pool import NullPool # optional for serverless
7
 
8
  from .config import settings
9
 
10
  raw_db_url = settings.DATABASE_URL
11
+
12
+ # Only add sslmode=require for remote connections, not localhost
13
+ if "sslmode=" not in raw_db_url and "localhost" not in raw_db_url and "127.0.0.1" not in raw_db_url:
14
+ raw_db_url = f"{raw_db_url}{'&' if '?' in raw_db_url else '?'}sslmode=require"
15
+
16
+ safe_url = make_url(raw_db_url).set(password="***")
17
+ print(f"database url: {safe_url}")
18
 
19
  engine = create_engine(
20
+ raw_db_url,
 
 
21
  pool_pre_ping=True,
22
+ pool_recycle=300,
23
+ # poolclass=NullPool,
24
+ # echo=True,
25
+ future=True,
26
  )
27
 
28
  SessionLocal = sessionmaker(
29
  autocommit=False,
30
  autoflush=False,
31
  bind=engine,
32
+ future=True,
33
  )
34
 
35
  Base = declarative_base()
py_backend/entrypoint.sh ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+ set -e
3
+
4
+ # show the DB host (redacts password automatically in our echo)
5
+ echo "Running alembic upgrade head..."
6
+ alembic upgrade head || { echo "Alembic failed"; exit 1; }
7
+
8
+ # start app (use the port Spaces injects)
9
+ exec uvicorn app.main:app --host 0.0.0.0 --port ${PORT:-7860}