Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Lebih memahami masalah `yield_per()` SQLalchemy

Kedua strategi pemuatan bermasalah menimbulkan pengecualian jika Anda mencoba menggunakannya dengan yield_per , jadi Anda tidak perlu terlalu khawatir.

Saya percaya satu-satunya masalah dengan subqueryload apakah pemuatan batch dari kueri kedua belum diterapkan (belum). Tidak ada yang salah secara semantik, tetapi jika Anda menggunakan yield_per , Anda mungkin memiliki alasan yang sangat bagus untuk tidak ingin memuat semua hasil sekaligus. Jadi SQLAlchemy dengan sopan menolak untuk melawan keinginan Anda.

joinedload sedikit lebih halus. Ini hanya dilarang dalam kasus koleksi, di mana baris utama mungkin memiliki beberapa baris terkait. Katakanlah kueri Anda menghasilkan hasil mentah seperti ini, di mana A dan B adalah kunci utama dari tabel yang berbeda:

 A | B 
---+---
 1 | 1 
 1 | 2 
 1 | 3 
 1 | 4 
 2 | 5 
 2 | 6 

Sekarang Anda mengambil ini dengan yield_per(3) . Masalahnya adalah SQLAlchemy hanya dapat membatasi berapa banyak yang diambil dengan baris , tetapi harus mengembalikan objek . Di sini, SQLAlchemy hanya melihat tiga baris pertama, sehingga menciptakan A objek dengan kunci 1 dan tiga B anak-anak:1, 2, dan 3.

Saat memuat batch berikutnya, ia ingin membuat A baru objek dengan kunci 1... ah, tetapi sudah memiliki salah satunya, jadi tidak perlu membuatnya lagi. B tambahan , 4, hilang. (Jadi, tidak, bahkan membaca koleksi gabungan dengan yield_per tidak aman — potongan data Anda mungkin hilang.)

Anda mungkin mengatakan "baik, teruslah membaca baris sampai Anda memiliki objek penuh" — tetapi bagaimana jika A itu memiliki seratus anak? Atau satu juta? SQLAlchemy tidak dapat menjamin secara wajar bahwa ia dapat melakukan apa yang Anda minta dan menghasilkan hasil yang benar, sehingga menolak untuk mencoba.

Ingatlah bahwa DBAPI dirancang agar apa saja database dapat digunakan dengan API yang sama, meskipun database tersebut tidak mendukung semua fitur DBAPI. Pertimbangkan bahwa DBAPI dirancang di sekitar kursor, tetapi MySQL sebenarnya tidak memiliki kursor! Adaptor DBAPI untuk MySQL harus memalsukannya.

Jadi sementara cursor.fetchmany(100) akan bekerja , Anda dapat melihat dari MySQLdb kode sumber bahwa itu tidak mengambil dengan malas dari server; itu mengambil semuanya ke dalam satu daftar besar, lalu mengembalikan sepotong ketika Anda memanggil fetchmany .

Apa psycopg2 mendukung adalah streaming yang sebenarnya, di mana hasilnya diingat terus-menerus di server, dan proses Python Anda hanya melihat beberapa di antaranya dalam satu waktu.

Anda masih dapat menggunakan yield_per dengan MySQLdb , atau DBAPI lainnya; itulah inti dari desain DBAPI. Anda harus membayar biaya memori untuk semua baris mentah yang tersembunyi di DBAPI (yang merupakan tupel, cukup murah), tetapi Anda tidak akan juga harus membayar semua objek ORM secara bersamaan.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Memasukkan data dari CSV ke MySQL DB sangat lambat

  2. Di MySQL, dapatkah saya menyalin satu baris untuk dimasukkan ke dalam tabel yang sama?

  3. Temukan jumlah total hasil dalam kueri mySQL dengan offset+limit

  4. Haruskah saya meneruskan variabel $mysqli saya ke setiap fungsi?

  5. Satu item kuis per halaman (program kuis php/mysql)