diff --git a/app/migration.py b/app/migration.py index 89ae255..5e45e23 100644 --- a/app/migration.py +++ b/app/migration.py @@ -4,12 +4,19 @@ import logging from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker +from sqlalchemy.orm import make_transient, sessionmaker from app.config import DB_PATH from app.models import MarketData, SymbolTimestamp from app.mysql_database import MySQLSessionLocal + +def _prepare_records_for_new_session(records): + """将 ORM 实例转换为可在新 session 中插入的 transient 状态。""" + for record in records: + make_transient(record) + record.id = None + logger = logging.getLogger(__name__) @@ -48,6 +55,9 @@ def migrate_sqlite_to_mysql(): finally: sqlite_session.close() + _prepare_records_for_new_session(market_data_records) + _prepare_records_for_new_session(symbol_timestamp_records) + if market_data_records: mysql_session.add_all(market_data_records) if symbol_timestamp_records: diff --git a/tests/test_dual_write_and_migration.py b/tests/test_dual_write_and_migration.py index b305830..244eb46 100644 --- a/tests/test_dual_write_and_migration.py +++ b/tests/test_dual_write_and_migration.py @@ -253,11 +253,6 @@ class TestMigrationIntegrity: assert len(added_symbol_timestamps) == 0 mysql_session.commit.assert_not_called() - @pytest.mark.xfail( - reason="app/migration.py 对 detached ORM 实例直接 add_all 不会触发 INSERT," - "需使用 make_transient() 或重新构造记录。", - strict=False, - ) def test_migration_end_to_end_with_in_memory_databases(self, tmp_path): """使用真实内存数据库验证迁移前后数据条数一致(当前已知缺陷)。""" sqlite_engine, sqlite_market_count, sqlite_timestamp_count = (