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'
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>
<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 ....我該如何解決?
<!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)
我目前的猜測還是說, 單獨跑.py 是能成功沒問題的
將一樣的.py 腳本放到 .html 裡頭跑就有報錯可能就是.html哪裡要再改改(我菜鳥的猜測)
然後就還是不排除 在本地跑 .py腳本的python 跟winSCP html page內建的<py-script>
互為獨立的實例,這樣
所以我還在努力看怎麼把新的報錯修一修
先給個結論,你不能以瀏覽器內的 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?
首先,感謝 froce 大在討論內幫解釋、勸告;因為我看到 jton 的新增回應,我身心都涼了~ ( 等等!我忘了開暖氣~
我先上個示意圖:
就 jton 的 .html
與 .py
的內容,還請輔以這簡陋示意圖來參考後續敘述。
.html
的內容,從 .html
內看到有需要下載的就會去下載,例如 .js
、 .css
檔案等。.html
內,就 JavaScript 方面,瀏覽器會去下載 pyscript.net
的 pyscript.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一樣,是一個在瀏覽器裡運作的語言環境,所有動作都會被瀏覽器本身限制住,(...)
目前瀏覽器沒提供這功能,就別期望想藉此突破天際了~
你的 get_sql_where.py 沒設好存取權限的話,會有資安風險。
不,他這個會跟js一樣一定得明文開放(要不然怎麼載入?)。所以一定資安風險極大。
我之所以連code都懶得幫他測試就是因為這根本不用測...
就我所知,不少網站軟體有提供檔案存取控制功能(例如客端網域限制、帳號組態等方式),只要「善用」那些功能或環境限制就行了。
(雖然一堆人都懶得閱覽文件而略過不管或放棄地裸奔~)
更何況 jton 沒說這些檔案放在哪使用;搞不好只是測試而把檔案放在區網或私網伺服器上而已。
(如果區網有風險,或是他用在啥詭異麻煩的情境,那也是他自己該承擔、處理的~)
而在資安風險上,除了伺服器組態、路由安全與瀏覽器等網路常見風險外,我倒是另外顧慮 PyScript 運作會不會有資安風險就是了~
畢竟發問者沒說他的環境、用途,我只能想到啥就提醒啥,最終風險還是由他自負。
(話說,若沒看到 froce 大的提醒,我大概也不會重複提醒吧~因為我關注於 PyScript 而已。)
反正我不會想這樣惡搞自己,我只是剛好閒閒且有點興趣而試試並分享經驗,讓 jton 多點經驗並少走點冤枉路罷了。
都很謝謝大家的建議,目前是想把這個方法先work再看有沒有其他方法能有類似效果。
我原本的想法是會把所有,包含 .py (有帳密的)放在WinSCP 裡, 其他人在html看,只能看到我有"import get_sql_where.py" 這句, 所以這樣應該能避免資安問題嗎?
我有把 re.Zero大大給的建議結果放到文章的更新裡了,方便的話可以看看
你放在SFTP裡,請問你要叫瀏覽器怎麼去連接SFTP?
就算可以,你是不是還是得在網頁裡寫連接SFTP的帳密?
pyscript就只是跟javascript一樣,是一個在瀏覽器裡運作的語言環境,所有動作都會被瀏覽器本身限制住,所以你不能開port、建立socket connection,而這是網路連線的基本,所以你要靠pyscript連DB根本不可能。
去好好學flask、Django這些網頁框架,不要浪費精力在pyscript了,這東西不是拿來這樣用的。他是拿來做邊緣運算、資料視覺化,補足一些數據專家不熟js和網頁前端這一塊的,並非所有python能做到的東西他都能做到。
現代任何一個網站框架搭配相關生態都能做到連接資料庫,把資料篩選出來,呈現在前端。
練習新技術不是異想天開,你要先了解他的基本、能做到什麼,不要別人跟你說牆在前面還一頭撞上還說好爽...
我懂大大的擔憂了 ( ^ω^)
那如果我的目標是 抓取mysql 上的資料並呈現在html上
目前手上有: "能抓mysql資料python的腳本"跟 "html網頁",原本計畫在html網頁直接跑python腳本,目前打消這個念頭了
但想問還有其他方法能有同樣效果嗎?
@jton:
若是「從資料庫取得資料後,呈現在網頁上」的情況,流行很久的 LAMP 方案/套件/組合 就有這能力。
就 「Apache、MySQL、PHP」 的組合情境下:
.php
)」時,回傳「.php
執行結果頁面」。.php
」內有 MySQL 的存取操作命令,那伺服端的 PHP runtime 就會依「伺服端的 .php
」內相關程式碼去存取 MySQL;在 PHP runtime 跑完「伺服端的 .php
」後,經由 Apache 傳回「.php
執行結果頁面」給客戶端瀏覽器。以上敘述,給你個基礎概念(這只是我久遠記憶中的概要流程,省略很多細節,可能有錯或變革,僅供參考~)。
有了基礎概念後,你再好好考慮你的方案或瀏覽其他技術、方案;或是另外發問,看有沒人提供更好、更貼近你需求的方案或意見。(畢竟電腦相關領域的知識,我只是因為興趣而淺嚐而已~)