2024-04-28

[Python] 使用 CnOcr 進行辨識時出現在 Windows/Linux 和 MacOSX 的結果不一樣的情況

最近公司的案子有要使用 OCR 辨識,然後技術方面是要用 python 去處理,公司的 RD 就利用 CnOcr 開發了一個程式…

然後最近這個案子的相關成員就跟老闆匯報進度跟問題,在會後老闆就在跟 RD 討論問題的部份,然後老闆就讓 RD 來找在下一起討論,看看我有沒有想法。

這邊遇到的問題是這樣的

因為 RD 在轉交辨識程式給案子其他的開發者時,有一位後端反應該程式運行時有狀況,無法正常辨識…先說明一下,該程式是要辨識表格中的數據,然後回傳某幾欄跟列的值,而遇到問題的後端是運行程式後,最後出現錯誤是『Indexerror: list index out of range』

我說: 這不就很明顯,就是辨識完後的結果並不存在指定的 index 位置
RD說: 是,但這不太可能,同一個程式用同一個模型去辨識同一個檔案,我在自己的環境跑是正常的
我說: 那有確定後端那邊的環境,python 安裝的套件的版本是一樣的嗎?
RD說: 是沒確認過,等等我問問
我說: 那你先把程式跟要辨識的檔案給我一份,我在我的環境用用看
....
我說: 我這邊跑是正常耶
RD說: 剛也跟後端確認過了,套件的版本是一樣的
我說: 後端那邊的系統是?
RD說: Mac電腦
我說: 呃,會是 MacOSX 有什麼特別的?比如 cpu 特別?或支援的指令集不同?
RD說: 這就不太確定了
老闆說: 公司這邊還有一台 Macbook Pro 2019 的,要不試試?
....
我說: 欸,奇了,在這台 Mac 跑也是有問題,而且問題的反饋還跟後端的不完全一樣…後端那邊反饋是應該要返回四個值,但結果是一個都沒有,可是公司這台的結果反而是有辨識到三個
....

2024-03-24

[Windows] docker desktop 4.26.0 開始會遇到 container 在啟動後維持了一定時間(大概30分鐘)時,外部host就無法對該容器進行操作

先說明,這有可能只是在下自己遇到的情況…

就是,某天在下 Windows 11 當時使用的 docker desktop 是在 4.25.0 然後更新到 4.26.0 時發生了一些奇怪的問題…

先說明在未更新前的環境

os: win11

cpu: amd ryzen 2700x

ram: 2 * 16G

app: docker desktop 4.25.0

containers: ubuntu 20.04 lts(內裝了 apache, php, mysql, phpmyadmin)

因為我大部份進行開發都是在公司上班時用工作機(筆電),當時工作機的 docker desktop 是更新到 4.25.2,家裡的桌機主要是為了在家工作時可以拿來開發,所以平時 docker desktop 我是不太會去更新

然後就有天看到有提醒有新版本 4.26.0 可以更新,我也沒想太多,就進行動作,然後更新完就把 docker desktop 關掉了,也沒去留意。

直到有天是公司 pm 告知客戶有反應前次更新有一些狀況,問我能不能先在家更新,更新完再來上班,我想說也行,就在30分鐘內完成了修正然後 hotfix 到客戶端去,正準備結束時就不知道為啥就按到了系統頁面的重新整理,結果發現一直在 loading…

2024-03-23

docker-compose 在 windows 環境該如何在 volumns 中設定掛載外部路徑

在 docker run 建立 container 的指令中,可以用 "-v {host-path}:{container-host-path}" 的方式來掛載主機路徑(host-path)至容器路徑(container-host-path)。

而主機路徑可以直接用絕對路徑的寫法,像 "-v D:\abc:/var/www/html"...

但,這方式在 docker-compose.yml 的 volumns 中這樣寫雖然不會報錯,但容器路徑 /var/www/html 卻會是空的,我假設 docker-compose.yml 中是這樣寫的(容器路徑我是假設的)
volumns:
  - "D:\abc:/var/www/html"
  - "./def:/var/www/html2"

"./def" 是以 docker-compose.yml 這個檔案的路徑開始中的 def 資料匣

我假定在 D:\abc 和 def 中都放了一個 index.html,在 container 啟動後,實際到 /var/www/html 路徑下查看,會發現是空的…而到 /var/www/html2 中查看則會有看到 index.html

在下試過很多寫法,但好像都無法掛載不是跟 docker-compose.yml 同路徑的其他路徑…但後來在 google 搜尋之後,發現了狀況,要掛載非 docker-compose.yml 同路徑的其他路徑,除了要寫絕對路徑的寫法外,寫法要改成

//{Disk drive}/path

例如: D:\abc 的掛載就要寫成

- "//d/abc:/var/www/html"

如此就能正常掛載到想要的外部路徑

註: 我自己後來把 docker desktop 在「用/不用 WSL」切換來切換去,有發現似乎「//d/abc」的這個方式是在「用 WSL」的情境下才有支援,「不用 WSL」的情境下還是要使用「D:\abc」的寫法,供大家參考

MySQL: ERROR...Aborted connection...to db: unconnected user:... host:... (init_connect command failed)... MySQL server has gone away!!

呃,沒錯,mysql 又遇坑了

不過遇上的前因是…我在把 apache, mysql, php-fpm, phpmyadmin 利用 docker 來運行在各自專屬的 container 上時,在 phpmyadmin 登入後所出現的訊息

因為這作法我沒有特別在 mysql 的 container 中去指定我自己優化的 mysql.cnf,而是改用 command 的命令加載去啟動的,所以我在 docker-compose.yml 中,mysql 的 command 的部份我有用到

command: [

...,

'--init_connect="SET NAMES utf8mb4"',

'--init_connect="SET collation_connection = utf8mb4_unicode_ci"'

]

然後 docker-compose up 的過程是沒什麼問題,當用 phpmyadmin 登入時就會看到頁面直接出現跟本篇標題差不多的文字,然後資料庫選單沒出現,重整網頁後也只是跳回登入,再次登比也是一樣。

這時我就直接進入 mysql container 內,直接用指令的方式登入

mysql -u {username} -p

剛登入是沒什麼異狀,但要求展示資料庫列表( show databases; )時就出現跟 phpmyadmin 登入時看到的異常訊息是一樣的( 註: 如果直接以高權限的帳戶登入,像 root 反而一切都很正常,沒有異常訊息 )

因為訊息中有提到 "init_connect command failed",所以先把 init_connect 的資料列出來看看

SHOW VARIABLES LIKE '%init_connect';

其結果為

| Variable_name |         Value       |
|-------------------------------------|
| init_connect  | 'SET NAMES utf8mb4' |

因為我有其他的 mysql 也有用到同樣的 init_connect 的命令,但是該命令是寫在 mysql.cnf 中,不是跟本次發生狀況的 mysql 一樣是用 docker 帶參數命令去生成的,所以我進到正常的 mysql 中看了一下,發現列出來的 init_connect 的值是不該帶有單引號的。

所以,我將 docker-compose.yml 中的 mysql 的 command 中有關於 init_connect 的命令改寫成

command: [

...,

'--init_connect=SET NAMES utf8mb4;SET collation_connection = utf8mb4_unicode_ci'

]
這樣 phpmyadmin 或 mysql 的登入就沒有再出現那個異常訊息了

2023-12-05

MySQL 沒有特別注意的 Collation 問題

這情況是一個我沒有特別發現,但是當出現錯誤時卻花了大把的時間 trace & debug 的事…

事由:

    我有兩個表,就叫 a 跟 b 好了

a {

  `id`: big integer, auto_increment, primary key,

  `sn`: varchar(50), utf8mb4_bin, unique key

}

b {

  `id`: big integer, auto_increment, primary key,

  `a_id`: big integer, foreign key references `a`.`id`,

  `sn`: varchar(50), utf8mb4_unicode_ci, unique key

}

我是後面接手維護的,我進行調整 a/b 表的 sn 的計算,利用 mysql trigger before insert 的時候去計算新的 sn,計算的操作是特別為了 a 跟 b 表各別寫一個 function 去做,就先叫 func_a 跟 func_b 好了

因為 b 跟 a 表的關係,所以 b.sn 的編碼格式中是有用到 a.sn 的,所以在 func_b 中,是要先以 NEW.`a_id` 到 a 表查 a.sn 後再回來用 a.sn 來串出 b.sn