2019年7月31日 星期三

[ Python 常見問題 ] SQLAlchemy: What's the difference between flush() and commit()?

Source From Here 
Question 
What the difference is between flush() and commit() in SQLAlchemy? 

I'm particularly interested in their impact on memory usage. I'm loading some data into a database from a series of files (around 5 million rows in total) and my session is occasionally falling over - it's a large database and a machine with not much memory. 

I'm wondering if I'm using too many commit() and not enough flush() calls - but without really understanding what the difference is, it's hard to tell! 

How-To 
Session object is basically an ongoing transaction of changes to a database (update, insert, delete). These operations aren't persisted to the database until they are committed (if your program aborts for some reason in mid-session transaction, any uncommitted changes within are lost). The session object registers transaction operations with session.add(), but doesn't yet communicate them to the database until session.flush() is called. 

session.flush() communicates a series of operations to the database (insert, update, delete). The database maintains them as pending operations in a transaction. The changes aren't persisted permanently to disk, or visible to other transactions until the database receives a COMMIT for the current transaction (which is what session.commit() does). 

commit() commits (persists) those changes to the database. flush() is always called as part of a call to commit() (1). 

When you use a Session object to query the database, the query will return results both from the database and from the flushed parts of the uncommitted transaction it holds. By default, Session objects autoflush their operations, but this can be disabled. Hopefully this example will make this clearer: 
  1. #---  
  2. s = Session()  
  3.   
  4. s.add(Foo('A')) # The Foo('A') object has been added to the session.  
  5.                 # It has not been committed to the database yet,  
  6.                 #   but is returned as part of a query.  
  7. print 1, s.query(Foo).all()  
  8. s.commit()  
  9.   
  10. #---  
  11. s2 = Session()  
  12. s2.autoflush = False  
  13.   
  14. s2.add(Foo('B'))  
  15. print 2, s2.query(Foo).all() # The Foo('B') object is *not* returned  
  16.                              #   as part of this query because it hasn't  
  17.                              #   been flushed yet.  
  18. s2.flush()                   # Now, Foo('B') is in the same state as  
  19.                              #   Foo('A') was above.  
  20. print 3, s2.query(Foo).all()   
  21. s2.rollback()                # Foo('B') has not been committed, and rolling  
  22.                              #   back the session's transaction removes it  
  23.                              #   from the session.  
  24. print 4, s2.query(Foo).all()  
  25.   
  26. #---  
  27. Output:  
  28. 1 ['A')>]  
  29. 2 ['A')>]  
  30. 3 ['A')>, 'B')>]  
  31. 4 ['A')>]  


Supplement 
FAQ - SQLAlchemy insert or update example

2019年7月28日 星期日

[ 文章收集 ] PostgreSQL 學習手冊 (模式 Schema)

Source From Here 
Preface 
一個數據庫包含一個或多個命名的模式,模式又包含表。模式還包含其它命名的物件,包括資料型別、函式,以及操作符。同一個物件名可以在不同的模式裡使用而不會導致衝突; 比如,schema1  myschema 都可以包含叫做 mytable 的表。和資料庫不同,模式不是嚴格分離的:一個使用者可以訪問他所連線的資料庫中的任意模式中的物件,只要他有許可權。 

我們需要模式有以下幾個主要原因: 
1). 允許多個使用者使用一個數據庫而不會干擾其它使用者。 
2). 把資料庫物件組織成邏輯組,讓它們更便於管理。 
3). 第三方的應用可以放在不同的模式中,這樣它們就不會和其它物件的名字衝突。

建立模式 - CREATE SCHEMA 
  1. CREATE SCHEMA myschema;  
通過以上命令可以建立名字為 myschema 的模式,在該模式被建立後,其便可擁有自己的一組邏輯物件,如表、檢視和函式等。 

public 模式 
在介紹後面的內容之前,這裡我們需要先解釋一下public模式。每當我們建立一個新的資料庫時,PostgreSQL都會為我們自動建立該模式。當登入到該資料庫時,如果沒有特殊的指定,我們將以該模式 (public) 的形式操作各種資料物件,如: 
  1. CREATE TABLE products ( ... )   
等同: 
  1. CREATE TABLE public.products ( ... )   
許可權 
預設時,使用者看不到模式中不屬於他們所有的物件。為了讓他們看得見,模式的所有者需要在模式上賦予 USAGE 許可權。為了讓使用者使用模式中的物件,我們可能需要賦予額外的許可權,只要是適合該物件的。PostgreSQL 根據不同的物件提供了不同的許可權型別,如: 
  1. GRANT ALL ON SCHEMA myschema TO public;  
上面的 ALL 關鍵字將包含 CREATE  USAGE 兩種許可權。如果 public 模式擁有了 myschema 模式的 CREATE 許可權,那麼登入到該模式的使用者將可以在 myschema 模式中建立任意物件,如: 
  1. CREATE TABLE myschema.products (   
  2.         product_no integer,   
  3.         name text,   
  4.         price numeric CHECK (price > 0),   
  5.     );   
在為模式下的所有表賦予許可權時,需要將許可權拆分為各種不同的表操作,如: 
  1. ALTER DEFAULT PRIVILEGES IN SCHEMA myschema   
  2.     GRANT INSERT, SELECT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER ON TABLES  TO public;   
在為模式下的所有 Sequence 序列物件賦予許可權時,需要將許可權拆分為各種不同的Sequence操作,如: 
  1. ALTER DEFAULT PRIVILEGES IN SCHEMA myschema   
  2.     GRANT SELECT, UPDATE, USAGE ON SEQUENCES TO public;  
在為模式下的所有函式賦予許可權時,僅考慮執行許可權,如: 
  1. ALTER DEFAULT PRIVILEGES IN SCHEMA myschema   
  2.     GRANT EXECUTE ON FUNCTIONS TO public;   
可以看出,通過以上方式在 public 模式下為 myschema 模式建立各種物件是極為不方便的。下面我們將要介紹另外一種方式,即通過role物件,直接登入並關聯到 myschema 物件,之後便可以在 myschema 模式下直接建立各種所需的物件了: 
  1. CREATE ROLE myschema LOGIN PASSWORD '123456';   --建立了和該模式關聯的角色物件。   
  2.    CREATE SCHEMA myschema AUTHORIZATION myschema;   --將該模式關聯到指定的角色,模式名和角  
色名可以不相等。 在Linux Shell下,以myschema的角色登入到資料庫MyTest,在密碼輸入正確後將成功登入到該資料庫: 
$ psql -d MyTest -U myschema 
Password: 

MyTest=> CREATE TABLE test(i integer); 
CREATE TABLE 

MyTest=> \d --檢視該模式下,以及該模式有許可權看到的tables資訊列表。 
  1.           List of relations   
  2. Schema     |   Name   | Type  |  Owner   
  3. ------------+---------+------+----------   
  4. myschema |   test     | table  | myschema   
  5. (1 rows)   

刪除模式 - DROP SCHEMA 
  1. DROP SCHEMA myschema;  
如果要刪除模式及其所有物件,請使用級聯刪除: 
  1. DROP SCHEMA myschema CASCADE;  
模式搜尋路徑 
我們在使用一個數據庫物件時可以使用它的全稱來定位物件,然而這樣做往往也是非常繁瑣的,每次都不得不鍵入owner_name.object_name。PostgreSQL 中提供了 模式搜尋路徑,這有些類似於 Linux 中的 $PATH 環境變數,當我們執行一個 Shell 命令時,只有該命令位於$PATH的目錄列表中,我們才可以通過命令名直接執行,否則就需要輸入它的全路徑名。PostgreSQL 同樣也通過查詢一個搜尋路徑來判斷一個表究竟是哪個表,這個路徑是一個需要查詢的模式列表。在搜尋路徑裡找到的第一個表將被當作選定的表。如果在搜尋路徑中 沒有匹配表,那麼就報告一個錯誤,即使匹配表的名字在資料庫其它的模式中存在也如此。 

在搜尋路徑中的第一個模式叫做 當前模式。除了是搜尋的第一個模式之外,它還是在 CREATE TABLE 沒有宣告模式名的時候,新建表所屬於的模式。要顯示當前搜尋路徑,使用下面的命令: 
MyTest=> SHOW search_path; 
  1. search_path   
  2. ---------------   
  3. "$user",public   
  4. 1 row)   

可以將新模式加入到搜尋路徑中,如: 
  1. SET search_path TO myschema,public;   
為搜尋路徑設定指定的模式,如: 
  1. SET search_path TO myschema; --當前搜尋路徑中將只是包含 myschema 一種模式。  
修改表的模式 
  1. alter table public.表名 set schema   新的模式名;  


[LeetCode] Easy - 942. DI String Match

Source From   Here Question How-To view plain copy to clipboard print ? #!/usr/bin/env python3   class   Solution:       def di...