pgsql_mysql_docker #4
12
.env.example
12
.env.example
@@ -23,4 +23,14 @@ AUTH_COOKIE_MAX_AGE=86400
|
||||
HEALTHCHECK_TOKEN=alamapsaikota123
|
||||
|
||||
# sesja zalogowanego usera (domyślnie 7 dni)
|
||||
SESSION_TIMEOUT_MINUTES=10080
|
||||
SESSION_TIMEOUT_MINUTES=10080
|
||||
|
||||
# Rodzaj bazy: sqlite, pgsql, mysql, firebird
|
||||
DB_ENGINE=sqlite
|
||||
|
||||
# Wspólne zmienne (dla pgsql, mysql, firebird)
|
||||
DB_HOST=db
|
||||
DB_PORT=5432
|
||||
DB_NAME=myapp
|
||||
DB_USER=user
|
||||
DB_PASSWORD=pass
|
||||
|
26
_tools/db/migrate.txt
Normal file
26
_tools/db/migrate.txt
Normal file
@@ -0,0 +1,26 @@
|
||||
Scenariusz migracji
|
||||
|
||||
Zatrzymaj obecny kontener:
|
||||
|
||||
|
||||
docker-compose down
|
||||
Ustaw w .env:
|
||||
|
||||
.env
|
||||
|
||||
DB_ENGINE=pgsql
|
||||
DB_NAME=myapp
|
||||
DB_USER=user
|
||||
DB_PASSWORD=pass
|
||||
Uruchom bazę i aplikację:
|
||||
|
||||
docker-compose --profile pgsql up -d
|
||||
Wykonaj migrację danych:
|
||||
|
||||
|
||||
bash _tools/db/migrate_to_new_db.sh pgsql
|
||||
|
||||
|
||||
|
||||
Sprawdź działanie aplikacji.
|
||||
|
49
_tools/db/migrate_sqlite_to_pgsql.py
Normal file
49
_tools/db/migrate_sqlite_to_pgsql.py
Normal file
@@ -0,0 +1,49 @@
|
||||
import os
|
||||
from sqlalchemy import create_engine, MetaData
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from config import Config
|
||||
|
||||
# Źródło: SQLite
|
||||
sqlite_engine = create_engine("sqlite:///instance/shopping.db")
|
||||
sqlite_meta = MetaData(bind=sqlite_engine)
|
||||
sqlite_meta.reflect()
|
||||
|
||||
# Cel: PostgreSQL (czytany z .env przez Config)
|
||||
pg_engine = create_engine(Config.SQLALCHEMY_DATABASE_URI)
|
||||
pg_meta = MetaData(bind=pg_engine)
|
||||
pg_meta.reflect()
|
||||
|
||||
# Sesje
|
||||
SQLiteSession = sessionmaker(bind=sqlite_engine)
|
||||
PGSession = sessionmaker(bind=pg_engine)
|
||||
|
||||
sqlite_session = SQLiteSession()
|
||||
pg_session = PGSession()
|
||||
|
||||
def migrate_table(table_name):
|
||||
print(f"Migruję tabelę: {table_name}")
|
||||
source_table = sqlite_meta.tables.get(table_name)
|
||||
target_table = pg_meta.tables.get(table_name)
|
||||
|
||||
if not source_table or not target_table:
|
||||
print(f"Pominięto: {table_name} (brak w jednej z baz)")
|
||||
return
|
||||
|
||||
rows = sqlite_session.execute(source_table.select()).fetchall()
|
||||
if not rows:
|
||||
print("Brak danych do migracji.")
|
||||
return
|
||||
|
||||
insert_data = [dict(row._mapping) for row in rows]
|
||||
with pg_engine.begin() as conn:
|
||||
conn.execute(target_table.insert(), insert_data)
|
||||
|
||||
print(f"✅ Przeniesiono: {len(rows)} rekordów")
|
||||
|
||||
def main():
|
||||
tables = ["user", "shopping_list", "item", "expense", "receipt", "suggested_product"]
|
||||
for table in tables:
|
||||
migrate_table(table)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
14
_tools/db/migrate_to_new_db.sh
Normal file
14
_tools/db/migrate_to_new_db.sh
Normal file
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
APP_CONTAINER=web
|
||||
DB_ENGINE=${1:-pgsql} # domyślnie pgsql
|
||||
|
||||
echo "Migracja z SQLite do $DB_ENGINE..."
|
||||
|
||||
docker-compose run --rm $APP_CONTAINER bash -c "
|
||||
export FLASK_APP=app.py
|
||||
flask db upgrade
|
||||
"
|
||||
|
||||
echo "Migracja zakończona."
|
19
config.py
19
config.py
@@ -3,7 +3,24 @@ import os
|
||||
|
||||
class Config:
|
||||
SECRET_KEY = os.environ.get("SECRET_KEY", "D8pceNZ8q%YR7^7F&9wAC2")
|
||||
SQLALCHEMY_DATABASE_URI = os.environ.get("DATABASE_URL", "sqlite:///shopping.db")
|
||||
|
||||
|
||||
DB_ENGINE = os.environ.get("DB_ENGINE", "sqlite").lower()
|
||||
|
||||
if DB_ENGINE == "sqlite":
|
||||
SQLALCHEMY_DATABASE_URI = "sqlite:///instance/shopping.db"
|
||||
elif DB_ENGINE == "pgsql":
|
||||
SQLALCHEMY_DATABASE_URI = f"postgresql://{os.environ['DB_USER']}:{os.environ['DB_PASSWORD']}@{os.environ['DB_HOST']}:{os.environ.get('DB_PORT', 5432)}/{os.environ['DB_NAME']}"
|
||||
elif DB_ENGINE == "mysql":
|
||||
SQLALCHEMY_DATABASE_URI = f"mysql+pymysql://{os.environ['DB_USER']}:{os.environ['DB_PASSWORD']}@{os.environ['DB_HOST']}:{os.environ.get('DB_PORT', 3306)}/{os.environ['DB_NAME']}"
|
||||
elif DB_ENGINE == "firebird":
|
||||
SQLALCHEMY_DATABASE_URI = f"firebird+fdb://{os.environ['DB_USER']}:{os.environ['DB_PASSWORD']}@{os.environ['DB_HOST']}/{os.environ['DB_NAME']}.fdb"
|
||||
else:
|
||||
raise ValueError("Nieobsługiwany typ bazy danych.")
|
||||
|
||||
|
||||
|
||||
|
||||
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
||||
SYSTEM_PASSWORD = os.environ.get("SYSTEM_PASSWORD", "admin")
|
||||
DEFAULT_ADMIN_USERNAME = os.environ.get("DEFAULT_ADMIN_USERNAME", "admin")
|
||||
|
@@ -8,6 +8,8 @@ echo "Pobieram najnowszy kod z repozytorium..."
|
||||
git pull
|
||||
|
||||
echo "Buduję obrazy i uruchamiam kontenery..."
|
||||
docker compose up -d --build
|
||||
#docker compose up -d --build
|
||||
DB_ENGINE=pgsql docker compose --profile pgsql up -d --build
|
||||
|
||||
|
||||
echo "Gotowe!"
|
||||
|
@@ -10,18 +10,53 @@ services:
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
environment:
|
||||
- FLASK_APP=app.py
|
||||
- FLASK_ENV=production
|
||||
- SECRET_KEY=${SECRET_KEY}
|
||||
- SYSTEM_PASSWORD=${SYSTEM_PASSWORD}
|
||||
- DEFAULT_ADMIN_USERNAME=${DEFAULT_ADMIN_USERNAME}
|
||||
- DEFAULT_ADMIN_PASSWORD=${DEFAULT_ADMIN_PASSWORD}
|
||||
- UPLOAD_FOLDER=${UPLOAD_FOLDER}
|
||||
- AUTHORIZED_COOKIE_VALUE=${AUTHORIZED_COOKIE_VALUE}
|
||||
- AUTH_COOKIE_MAX_AGE=${AUTH_COOKIE_MAX_AGE}
|
||||
- HEALTHCHECK_TOKEN=${HEALTHCHECK_TOKEN}
|
||||
- SESSION_TIMEOUT_MINUTES=${SESSION_TIMEOUT_MINUTES}
|
||||
env_file:
|
||||
- .env
|
||||
volumes:
|
||||
- .:/app
|
||||
restart: unless-stopped
|
||||
- ./uploads:/app/uploads
|
||||
- ./instance:/app/instance
|
||||
restart: unless-stopped
|
||||
# depends_on:
|
||||
# - ${DB_ENGINE:-sqlite}
|
||||
|
||||
pgsql:
|
||||
image: postgres:17
|
||||
container_name: pgsql-db
|
||||
environment:
|
||||
POSTGRES_DB: ${DB_NAME}
|
||||
POSTGRES_USER: ${DB_USER}
|
||||
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
||||
volumes:
|
||||
- ./db/pgsql:/var/lib/postgresql/data
|
||||
ports:
|
||||
- "5432:5432"
|
||||
restart: unless-stopped
|
||||
profiles: ["pgsql"]
|
||||
|
||||
mysql:
|
||||
image: mysql:8
|
||||
container_name: mysql-db
|
||||
environment:
|
||||
MYSQL_DATABASE: ${DB_NAME}
|
||||
MYSQL_USER: ${DB_USER}
|
||||
MYSQL_PASSWORD: ${DB_PASSWORD}
|
||||
MYSQL_ROOT_PASSWORD: root
|
||||
volumes:
|
||||
- ./db/mysql:/var/lib/mysql
|
||||
ports:
|
||||
- "3306:3306"
|
||||
restart: unless-stopped
|
||||
profiles: ["mysql"]
|
||||
|
||||
firebird:
|
||||
image: jacobalberty/firebird
|
||||
container_name: firebird-db
|
||||
environment:
|
||||
ISC_PASSWORD: ${DB_PASSWORD}
|
||||
volumes:
|
||||
- ./db/firebird:/firebird/data
|
||||
ports:
|
||||
- "3050:3050"
|
||||
restart: unless-stopped
|
||||
profiles: ["firebird"]
|
||||
|
@@ -10,4 +10,4 @@ psutil
|
||||
pillow-heif
|
||||
|
||||
pytesseract
|
||||
opencv-python-headless
|
||||
opencv-python-headless
|
||||
|
Reference in New Issue
Block a user