multidb
This commit is contained in:
@@ -6,7 +6,7 @@ PYTHONPATH=. python3 _tools/db/migrate_sqlite_to_pgsql.py
|
|||||||
rm -rf venv_migrate
|
rm -rf venv_migrate
|
||||||
|
|
||||||
# reset wszystkich sekwencji w pgsql
|
# reset wszystkich sekwencji w pgsql
|
||||||
docker exec -it pgsql-db psql -U zbiorki -d zbiorki
|
docker exec -it zbiorka-pgsql-db psql -U zbiorki -d zbiorki
|
||||||
|
|
||||||
|
|
||||||
DO $$
|
DO $$
|
||||||
|
@@ -1,23 +1,28 @@
|
|||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../../")))
|
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../../")))
|
||||||
|
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
from sqlalchemy import create_engine, MetaData
|
from sqlalchemy import create_engine, MetaData
|
||||||
from sqlalchemy.orm import sessionmaker
|
from sqlalchemy.orm import sessionmaker
|
||||||
from config import Config
|
from config import Config
|
||||||
from dotenv import load_dotenv
|
|
||||||
load_dotenv()
|
|
||||||
|
|
||||||
# Źródło: SQLite
|
# Źródło: SQLite
|
||||||
sqlite_engine = create_engine("sqlite:///instance/baza.db")
|
sqlite_engine = create_engine("sqlite:///instance/baza.db")
|
||||||
sqlite_meta = MetaData()
|
sqlite_meta = MetaData()
|
||||||
sqlite_meta.reflect(bind=sqlite_engine)
|
sqlite_meta.reflect(bind=sqlite_engine)
|
||||||
|
|
||||||
|
|
||||||
# Cel: PostgreSQL
|
# Cel: PostgreSQL
|
||||||
pg_engine = create_engine(Config.SQLALCHEMY_DATABASE_URI)
|
pg_engine = create_engine(Config.SQLALCHEMY_DATABASE_URI)
|
||||||
pg_meta = MetaData()
|
pg_meta = MetaData()
|
||||||
pg_meta.reflect(bind=pg_engine)
|
pg_meta.reflect(bind=pg_engine)
|
||||||
|
|
||||||
|
|
||||||
# Sesje
|
# Sesje
|
||||||
SQLiteSession = sessionmaker(bind=sqlite_engine)
|
SQLiteSession = sessionmaker(bind=sqlite_engine)
|
||||||
PGSession = sessionmaker(bind=pg_engine)
|
PGSession = sessionmaker(bind=pg_engine)
|
||||||
@@ -25,19 +30,20 @@ PGSession = sessionmaker(bind=pg_engine)
|
|||||||
sqlite_session = SQLiteSession()
|
sqlite_session = SQLiteSession()
|
||||||
pg_session = PGSession()
|
pg_session = PGSession()
|
||||||
|
|
||||||
|
|
||||||
def migrate_table(table_name):
|
def migrate_table(table_name):
|
||||||
print("➡️ Używana baza docelowa:", Config.SQLALCHEMY_DATABASE_URI)
|
print("Używana baza docelowa:", Config.SQLALCHEMY_DATABASE_URI)
|
||||||
print(f"\n➡️ Migruję tabelę: {table_name}")
|
print(f"Migruję tabelę: {table_name}")
|
||||||
source_table = sqlite_meta.tables.get(table_name)
|
source_table = sqlite_meta.tables.get(table_name)
|
||||||
target_table = pg_meta.tables.get(table_name)
|
target_table = pg_meta.tables.get(table_name)
|
||||||
|
|
||||||
if source_table is None or target_table is None:
|
if source_table is None or target_table is None:
|
||||||
print(f"⚠️ Pominięto: {table_name} (brak w jednej z baz)")
|
print(f"Pominięto: {table_name} (brak w jednej z baz)")
|
||||||
return
|
return
|
||||||
|
|
||||||
rows = sqlite_session.execute(source_table.select()).fetchall()
|
rows = sqlite_session.execute(source_table.select()).fetchall()
|
||||||
if not rows:
|
if not rows:
|
||||||
print("ℹ️ Brak danych do migracji.")
|
print("Brak danych do migracji.")
|
||||||
return
|
return
|
||||||
|
|
||||||
insert_data = [dict(row._mapping) for row in rows]
|
insert_data = [dict(row._mapping) for row in rows]
|
||||||
@@ -46,16 +52,17 @@ def migrate_table(table_name):
|
|||||||
with pg_engine.begin() as conn:
|
with pg_engine.begin() as conn:
|
||||||
conn.execute(target_table.delete())
|
conn.execute(target_table.delete())
|
||||||
conn.execute(target_table.insert(), insert_data)
|
conn.execute(target_table.insert(), insert_data)
|
||||||
print(f"✅ Przeniesiono: {len(rows)} rekordów")
|
print(f"Przeniesiono: {len(rows)} rekordów")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"❌ Błąd przy migracji {table_name}: {e}")
|
print(f"Błąd przy migracji {table_name}: {e}")
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
tables = ["user", "shopping_list", "item", "expense", "receipt", "suggested_product"]
|
tables = ["zbiorka", "przedmiot", "uzytkownik", "wydatek", "ustawienia_globalne", "wplata"]
|
||||||
for table in tables:
|
for table in tables:
|
||||||
migrate_table(table)
|
migrate_table(table)
|
||||||
print("\n🎉 Migracja zakończona pomyślnie.")
|
print("\nMigracja zakończona pomyślnie.")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
2
app.py
2
app.py
@@ -178,6 +178,7 @@ def load_user(user_id):
|
|||||||
|
|
||||||
@event.listens_for(Engine, "connect")
|
@event.listens_for(Engine, "connect")
|
||||||
def set_sqlite_pragma(dbapi_connection, connection_record):
|
def set_sqlite_pragma(dbapi_connection, connection_record):
|
||||||
|
if dbapi_connection.__class__.__module__.startswith('sqlite3'):
|
||||||
try:
|
try:
|
||||||
cursor = dbapi_connection.cursor()
|
cursor = dbapi_connection.cursor()
|
||||||
cursor.execute("PRAGMA foreign_keys=ON")
|
cursor.execute("PRAGMA foreign_keys=ON")
|
||||||
@@ -185,7 +186,6 @@ def set_sqlite_pragma(dbapi_connection, connection_record):
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def get_real_ip():
|
def get_real_ip():
|
||||||
headers = request.headers
|
headers = request.headers
|
||||||
cf_ip = headers.get("CF-Connecting-IP")
|
cf_ip = headers.get("CF-Connecting-IP")
|
||||||
|
13
deploy.sh
13
deploy.sh
@@ -19,6 +19,19 @@ GIT_BRANCH="${GIT_BRANCH:-$(git -C "$REPO_DIR" rev-parse --abbrev-ref HEAD 2>/de
|
|||||||
DB_PROFILE="sqlite" # domyślnie sqlite, czyli brak profilu pgsql/mysql
|
DB_PROFILE="sqlite" # domyślnie sqlite, czyli brak profilu pgsql/mysql
|
||||||
SERVICES=()
|
SERVICES=()
|
||||||
|
|
||||||
|
# Tworzenie katalogów danych dla baz jeśli brak
|
||||||
|
if [[ "$DB_PROFILE" == "pgsql" ]]; then
|
||||||
|
if [[ ! -d "./db/pgsql" ]]; then
|
||||||
|
log "Tworzę katalog ./db/pgsql dla danych PostgreSQL"
|
||||||
|
mkdir -p ./db/pgsql
|
||||||
|
fi
|
||||||
|
elif [[ "$DB_PROFILE" == "mysql" ]]; then
|
||||||
|
if [[ ! -d "./db/mysql" ]]; then
|
||||||
|
log "Tworzę katalog ./db/mysql dla danych MySQL"
|
||||||
|
mkdir -p ./db/mysql
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# Przetwarzanie argumentów
|
# Przetwarzanie argumentów
|
||||||
if [[ $# -gt 0 ]]; then
|
if [[ $# -gt 0 ]]; then
|
||||||
case "$1" in
|
case "$1" in
|
||||||
|
@@ -42,7 +42,7 @@ services:
|
|||||||
|
|
||||||
pgsql:
|
pgsql:
|
||||||
image: postgres:17
|
image: postgres:17
|
||||||
container_name: pgsql-db
|
container_name: zbiorka-pgsql-db
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_DB: ${DB_NAME}
|
POSTGRES_DB: ${DB_NAME}
|
||||||
POSTGRES_USER: ${DB_USER}
|
POSTGRES_USER: ${DB_USER}
|
||||||
@@ -54,7 +54,7 @@ services:
|
|||||||
|
|
||||||
mysql:
|
mysql:
|
||||||
image: mysql:8
|
image: mysql:8
|
||||||
container_name: mysql-db
|
container_name: zbiorka-mysql-db
|
||||||
environment:
|
environment:
|
||||||
MYSQL_DATABASE: ${DB_NAME}
|
MYSQL_DATABASE: ${DB_NAME}
|
||||||
MYSQL_USER: ${DB_USER}
|
MYSQL_USER: ${DB_USER}
|
||||||
|
@@ -4,3 +4,6 @@ Flask-Login
|
|||||||
Werkzeug
|
Werkzeug
|
||||||
waitress
|
waitress
|
||||||
markdown
|
markdown
|
||||||
|
psycopg2-binary # pgsql
|
||||||
|
pymysql # mysql
|
||||||
|
cryptography # mysql8
|
Reference in New Issue
Block a user