iT邦幫忙

0

ModuleNotFoundError: No module named 'mysql' ;感覺為 <py-config> tag 需要再修改一下

jton 2023-01-30 18:08:491043 瀏覽
  • 分享至 

  • xImage
  • python腳本可以自行執行
    (邏輯上我已經 pip 安裝我需要的所有東西)
import mysql.connector
import webbrowser
import time
import pymysql

mydb = mysql.connector.connect(
  host="196.168.16.144",
  user="root",
  password="password123", 
  database="cloud_db",  
  auth_plugin='mysql_native_password'
)
                
mycursor = mydb.cursor()
mycursor.execute("SELECT P_TITLE,P_DESC  FROM webpage WHERE P_ID = 'en_1-01'")                       
                                         
myresult = mycursor.fetchall()

print(myresult)    

但是在 html 中運行/執行時遇到 ModuleNotFoundError: No module named 'mysql'

  • error message 錯誤信息

Traceback (most recent call last):
File "/lib/python3.10/site-packages/_pyodide/_base.py", line 435, in eval_code
.run(globals, locals)
File "/lib/python3.10/site-packages/_pyodide/_base.py", line 304, in run
coroutine = eval(self.code, globals, locals)
File "exec", line 4, in
ModuleNotFoundError: No module named 'mysql'

  • 在 html 中運行 py 腳本
<html>
    <head>
      <link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
      <script defer src="https://pyscript.net/latest/pyscript.js"></script>
    </head>

  <body>
    <b><p>this is the info from sql</p></b>
    <br>
  
    <py-config>
      [[fetch]]
      files = ["./get_sql_where.py"]

      packages = ["mysql"]
    </py-config>

    <py-script src="get_sql_where.py">
        import pymysql
        import get_sql_where.py
      
    </py-script>
  </body>
</html>

問題:我已經嘗試過 <py-config> 但仍然面臨 ModuleNotFoundError,mysql ....我該如何解決?


  • 更新: 根據re.Zero大大的修改
<!DOCTYPE html>
<!-- myPyScriptRun.html -->
<html><head>
	<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
	<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head><body>
	<b><p>this is the info from sql</p></b><br>
	<py-config>
packages = ["mysql-connector-python", "PyMySQL"]
	</py-config>
	<py-script src="./get_sql_where.py" />
</body></html>
  • 這是新的報錯,算是有往好的方向邁進嗎?哈哈
Traceback (most recent call last):
  File "/lib/python3.10/site-packages/mysql/connector/network.py", line 600, in open_connection
    self.sock.connect(sockaddr)
BlockingIOError: [Errno 26] Operation in progress

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/lib/python3.10/site-packages/_pyodide/_base.py", line 435, in eval_code
    .run(globals, locals)
  File "/lib/python3.10/site-packages/_pyodide/_base.py", line 304, in run
    coroutine = eval(self.code, globals, locals)
  File "<exec>", line 9, in <module>
  File "/lib/python3.10/site-packages/mysql/connector/pooling.py", line 294, in connect
    return MySQLConnection(*args, **kwargs)
  File "/lib/python3.10/site-packages/mysql/connector/connection.py", line 167, in __init__
    self.connect(**kwargs)
  File "/lib/python3.10/site-packages/mysql/connector/abstracts.py", line 1178, in connect
    self._open_connection()
  File "/lib/python3.10/site-packages/mysql/connector/connection.py", line 571, in _open_connection
    self._socket.open_connection()
  File "/lib/python3.10/site-packages/mysql/connector/network.py", line 602, in open_connection
    raise InterfaceError(
mysql.connector.errors.InterfaceError: 2003: Can't connect to MySQL server on '196.168.1.141:3306' (26 Operation in progress)

https://ithelp.ithome.com.tw/upload/images/20230201/20153034alkznWZKIk.png

  1. 我目前的猜測還是說, 單獨跑.py 是能成功沒問題的

  2. 將一樣的.py 腳本放到 .html 裡頭跑就有報錯可能就是.html哪裡要再改改(我菜鳥的猜測)

  3. 然後就還是不排除 在本地跑 .py腳本的python 跟winSCP html page內建的<py-script> 互為獨立的實例,這樣

所以我還在努力看怎麼把新的報錯修一修

froce iT邦大師 1 級 ‧ 2023-01-30 21:48:16 檢舉
1. 你應該得架一個web server,並且把你自己寫的py 也放在server上。
2. 你的import也寫的不對,不會有.py這個副檔名。
3. 你要的東西用正常的web framework就能做了,而且做得更好。
4. 你這樣會把sql server的帳號密碼都放在前端。科科
jton iT邦新手 5 級 ‧ 2023-02-01 09:02:08 檢舉
1. 我原本的想法是,會把 .py (有帳密的)放在WinSCP 裡, 其他人在html看,只能看到我有import get_sql_where.py 所以這樣應該能避免資安問題嗎?
2. 我等會改 import
3. web Framework 例如 flask, django 我大概知道,可是具體是哪個專有名詞能做到一樣的效果,想跟哥問一下

謝謝哥指教
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

2
re.Zero
iT邦研究生 5 級 ‧ 2023-01-30 23:26:23
最佳解答
  • Update: 新增補充說明於主文後。

先給個結論,你不能以瀏覽器內的 PyScript (Pyodide + WASM + ...) 透過一般的 SQL driver 去連線 SQL 伺服器;這限制是基於瀏覽器的保安機制(或說,"Python 標準函式庫 socket" 在 "WebAssembly VM" 上實作程度的限制)。
這篇 Improve documentation and error reporting for lack of networking in Pyodide and PyScript 有稍微說到該狀況。


  • python腳本可以自行執行
    (邏輯上我已經 pip 安裝我需要的所有東西)

希望這段語意不是表示你搞混了某些狀況,但我還是提醒一下:
瀏覽器內的 PyScript 與作業系統上的 CPython (Python 官方實作) 是互為獨立的實例。


froce 大已提到,但我再重提一次:
你的 get_sql_where.py 沒做好存取控管的話,會有資安風險。

(畢竟資料庫的帳密放在裡面……)


你在 CPython 使用非內建的模組時,需要透過 pip 安裝 pypi (Python 套件索引 (Python Package Index)) 上的套件以引入作業環境,例如:

pip install mysql-connector-python
pip install PyMySQL

而在 PyScript 上,從其官網說明文件的 Importing the needed libraries 可推知,可用下面方式引入作業環境:

<py-config>
packages = ["mysql-connector-python", "PyMySQL"]
</py-config>

PyScript 官方文件 內有 py-script 的用法說明,請「擇一」使用:
(未來會不會支援混用我不知道,但我現在沒看到)

<py-script src="./get_sql_where.py"></py-script>

最後,丟個我的沒用途範例:

<!DOCTYPE html>
<!-- myPyScriptRun.html -->
<html><head>
	<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
	<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head><body>
	<b><p>this is the info from sql</p></b><br>
	<py-config>
packages = ["mysql-connector-python", "PyMySQL"]
	</py-config>
	<py-script src="./get_sql_where.py" />
</body></html>
## get_sql_where.py
## 這是 socket 的測試;我這邊是顯示 172.29.1.0 (Private IPv4);
import socket
hostname = 'google.com'
print('myTry:', socket.gethostbyname(hostname))
## 
import mysql.connector
import webbrowser
import time
import pymysql
## 
print("Start:")
## 
try: ## 這邊大概只會出錯~畢竟連不出去~
	mydb = mysql.connector.connect(
		host="196.168.16.144",
		user="root",
		password="password123", 
		database="cloud_db",  
		auth_plugin='mysql_native_password'
	)
	mycursor = mydb.cursor()
	mycursor.execute("SELECT P_TITLE,P_DESC  FROM webpage WHERE P_ID = 'en_1-01'")
	myresult = mycursor.fetchall()
	print(myresult)
	## 
	mydb.close()
except Exception as err: print('□ Exception:[' + type(err).__name__ + ']: ',end=''); print(err)
## 
print("End?")
## 

我的輸出(in py-terminal):

myTry: 172.29.1.0
Start:
□ Exception:[InterfaceError]: 2003: Can't connect to MySQL server on '196.168.16.144:3306' (26 Operation in progress)
End?

  • Update:

首先,感謝 froce 大在討論內幫解釋、勸告;因為我看到 jton 的新增回應,我身心都涼了~ ( 等等!我忘了開暖氣~

我先上個示意圖:

https://ithelp.ithome.com.tw/upload/images/20230201/20155649xTiw1qj0KG.png

jton.html.py 的內容,還請輔以這簡陋示意圖來參考後續敘述。

  • 開啟瀏覽器輸入網址後,瀏覽器會依網址去取得 .html 的內容,從 .html 內看到有需要下載的就會去下載,例如 .js.css 檔案等。
  • jton.html 內,就 JavaScript 方面,瀏覽器會去下載 pyscript.netpyscript.js,依該檔案的內容運作,建立 PyScript 的環境/運行。
  • <py-script src="./get_sql_where.py" /> 這段,會使 PyScript 讓瀏覽器請求下載 .html 所在網址上的 ./get_sql_where.py 檔案,以讓 PyScript 能執行其內容。

這邊就是 froce 大強調的危險之處:因為若 ./get_sql_where.py 沒經過控管,就能被公開存取、下載,這很危險;就算你用「以 <py-config>[[fetch]] 給 Python import」的方式,也是一樣的運作方式(瀏覽器得下載給 PyScript),而其他人只要去下載那些檔案就能看到內容了。
(如果你的問題是別人要怎樣知道下載那些檔案,只要看程式碼或用 [F12] 開啟的 DevTools 就行了…)

在前段說明與示意圖中,展示出 PyScript 運作在瀏覽器內,該環境就如 froce 大所說:

pyscript就只是跟javascript一樣,是一個在瀏覽器裡運作的語言環境,所有動作都會被瀏覽器本身限制住,(...)

目前瀏覽器沒提供這功能,就別期望想藉此突破天際了~

看更多先前的回應...收起先前的回應...
froce iT邦大師 1 級 ‧ 2023-01-31 08:17:39 檢舉

你的 get_sql_where.py 沒設好存取權限的話,會有資安風險。

不,他這個會跟js一樣一定得明文開放(要不然怎麼載入?)。所以一定資安風險極大。

我之所以連code都懶得幫他測試就是因為這根本不用測...

re.Zero iT邦研究生 5 級 ‧ 2023-01-31 17:28:06 檢舉

就我所知,不少網站軟體有提供檔案存取控制功能(例如客端網域限制、帳號組態等方式),只要「善用」那些功能或環境限制就行了。
(雖然一堆人都懶得閱覽文件而略過不管或放棄地裸奔~)
更何況 jton 沒說這些檔案放在哪使用;搞不好只是測試而把檔案放在區網或私網伺服器上而已。
(如果區網有風險,或是他用在啥詭異麻煩的情境,那也是他自己該承擔、處理的~)
而在資安風險上,除了伺服器組態、路由安全與瀏覽器等網路常見風險外,我倒是另外顧慮 PyScript 運作會不會有資安風險就是了~
畢竟發問者沒說他的環境、用途,我只能想到啥就提醒啥,最終風險還是由他自負。
(話說,若沒看到 froce 大的提醒,我大概也不會重複提醒吧~因為我關注於 PyScript 而已。)
反正我不會想這樣惡搞自己,我只是剛好閒閒且有點興趣而試試並分享經驗,讓 jton 多點經驗並少走點冤枉路罷了。

jton iT邦新手 5 級 ‧ 2023-02-01 09:17:47 檢舉

都很謝謝大家的建議,目前是想把這個方法先work再看有沒有其他方法能有類似效果。

我原本的想法是會把所有,包含 .py (有帳密的)放在WinSCP 裡, 其他人在html看,只能看到我有"import get_sql_where.py" 這句, 所以這樣應該能避免資安問題嗎?

jton iT邦新手 5 級 ‧ 2023-02-01 09:32:01 檢舉

我有把 re.Zero大大給的建議結果放到文章的更新裡了,方便的話可以看看

froce iT邦大師 1 級 ‧ 2023-02-01 11:24:30 檢舉

你放在SFTP裡,請問你要叫瀏覽器怎麼去連接SFTP?
就算可以,你是不是還是得在網頁裡寫連接SFTP的帳密?

pyscript就只是跟javascript一樣,是一個在瀏覽器裡運作的語言環境,所有動作都會被瀏覽器本身限制住,所以你不能開port、建立socket connection,而這是網路連線的基本,所以你要靠pyscript連DB根本不可能。

去好好學flask、Django這些網頁框架,不要浪費精力在pyscript了,這東西不是拿來這樣用的。他是拿來做邊緣運算、資料視覺化,補足一些數據專家不熟js和網頁前端這一塊的,並非所有python能做到的東西他都能做到。

現代任何一個網站框架搭配相關生態都能做到連接資料庫,把資料篩選出來,呈現在前端。

練習新技術不是異想天開,你要先了解他的基本、能做到什麼,不要別人跟你說牆在前面還一頭撞上還說好爽...

re.Zero iT邦研究生 5 級 ‧ 2023-02-01 20:32:21 檢舉

感謝 froce 大幫忙解釋~

@jton: 我更新補上一些內容,希望你能了解 PyScript 在你的應用方向上之限制與風險。

jton iT邦新手 5 級 ‧ 2023-02-02 11:25:16 檢舉

我懂大大的擔憂了 ( ^ω^)

那如果我的目標是 抓取mysql 上的資料並呈現在html上

目前手上有: "能抓mysql資料python的腳本"跟 "html網頁",原本計畫在html網頁直接跑python腳本,目前打消這個念頭了

但想問還有其他方法能有同樣效果嗎?

re.Zero iT邦研究生 5 級 ‧ 2023-02-02 21:37:23 檢舉

@jton
若是「從資料庫取得資料後,呈現在網頁上」的情況,流行很久的 LAMP 方案/套件/組合 就有這能力。
就 「Apache、MySQL、PHP」 的組合情境下:

  • 當客戶端瀏覽器向伺服端 HTTP Service (Apache) 請求網頁或資源時,Apache 就會(依 Apache 的組態)傳回客戶端瀏覽器所要的網頁或資源。
  • 在 Apache 備妥 PHP 運作環境下,Apache 就能在客戶端瀏覽器要求「需要 PHP 直譯器運作的頁面(.php)」時,回傳「.php 執行結果頁面」。
  • 若「伺服端的 .php」內有 MySQL 的存取操作命令,那伺服端的 PHP runtime 就會依「伺服端的 .php」內相關程式碼去存取 MySQL;在 PHP runtime 跑完「伺服端的 .php」後,經由 Apache 傳回「.php 執行結果頁面」給客戶端瀏覽器。

以上敘述,給你個基礎概念(這只是我久遠記憶中的概要流程,省略很多細節,可能有錯或變革,僅供參考~)。
有了基礎概念後,你再好好考慮你的方案或瀏覽其他技術、方案;或是另外發問,看有沒人提供更好、更貼近你需求的方案或意見。(畢竟電腦相關領域的知識,我只是因為興趣而淺嚐而已~)

我要發表回答

立即登入回答