在Linux服务上无法导入pandas库。

huangapple go评论80阅读模式
英文:

Unable to import pandas on a linux service

问题

我正在尝试使用Python创建一个简单的服务,并且该服务需要导入pandas来操作数据框。我注意到当我使用"import pandas as pd"时,服务会失败。我创建了一个示例来展示这种行为。

脚本main2.py(位置:/home/silas/Desktop):

import pandas as pd
import logging
import time

while True:
    print('hello world')

    time.sleep(10)

my_service.service(位置:/etc/systemd/system):

[Unit]
Description=Example
After=network.target

[Service]
ExecStart=/usr/bin/python3 /home/silas/Desktop/main2.py
Restart=always

[Install]
WantedBy=default.target

我打开终端并执行了以下命令:

systemctl start my_service.service
systemctl enable my_service.service
systemctl status my_service.service

我得到的响应告诉我我的服务没有运行并且失败了:

 my_service.service - Example
      Loaded: loaded (/etc/systemd/system/my_service.service; enabled; vendor pr>
      Active: failed (Result: exit-code) since Tue 2023-08-08 19:49:53 -03; 1min>
 Main PID: 8776 (code=exited, status=1/FAILURE)
    CPU: 63ms

如果我将脚本更改为:

 import logging
 import time


 while True:

     print('hello world')

     time.sleep(10)

并执行以下命令:

systemctl stop my_service.service
systemctl disable my_service.service
systemctl start my_service.service
systemctl enable my_service.service
systemctl status my_service.service

我得到的响应告诉我服务正在运行:

my_service.service - Example
     Loaded: loaded (/etc/systemd/system/my_service.service; enabled; vendor pr>
     Active: active (running) since Tue 2023-08-08 19:54:31 -03; 10s ago
   Main PID: 8952 (python3)
      Tasks: 1 (limit: 8994)
     Memory: 4.2M
        CPU: 26ms
     CGroup: /system.slice/my_service.service
             └─8952 /usr/bin/python3 /home/silas/Desktop/main2.py

是否可以以这种方式使用pandas?如果可以,我做错了什么?如果不可能,我该如何创建一个使用pandas的服务?

注意1:Pandas已安装在我的机器上,我没有使用虚拟环境。

注意2:如果我使用python3 main2.py执行脚本,可以正常工作并且可以使用pandas。

注意3:如果我在终端中输入which python3,会显示my_service.service中配置的路径。

英文:

I'm trying to create a simple service using Python and the service needs to import pandas for manipulating dataframes. I noticed that when I use "import pandas as pd", the service failed. I created a example to show the behavior.

Script main2.py (location: /home/silas/Desktop):

import pandas as pd
import logging
import time

while True:
    print('hello world')

    time.sleep(10)

my_service.service (location: /etc/systemd/system):

[Unit]
Description=Example
After=network.target

[Service]
ExecStart=/usr/bin/python3 /home/silas/Desktop/main2.py
Restart=always

[Install]
WantedBy=default.target

I opened the prompt and executed the commands:

systemctl start my_service.service
systemctl enable my_service.service
systemctl status my_service.service

I got the response telling me that my service is not running and failed:

 my_service.service - Example
      Loaded: loaded (/etc/systemd/system/my_service.service; enabled; vendor pr>
      Active: failed (Result: exit-code) since Tue 2023-08-08 19:49:53 -03; 1min>
 Main PID: 8776 (code=exited, status=1/FAILURE)
    CPU: 63ms

If I change the script to:

 import logging
 import time


 while True:

     print('hello world')

     time.sleep(10)

And execute the commands:

systemctl stop my_service.service
systemctl disable my_service.service
systemctl start my_service.service
systemctl enable my_service.service
systemctl status my_service.service

I got the response telling me that the service is running:

y_service.service - Example
     Loaded: loaded (/etc/systemd/system/my_service.service; enabled; vendor pr>
     Active: active (running) since Tue 2023-08-08 19:54:31 -03; 10s ago
   Main PID: 8952 (python3)
      Tasks: 1 (limit: 8994)
     Memory: 4.2M
        CPU: 26ms
     CGroup: /system.slice/my_service.service
             └─8952 /usr/bin/python3 /home/silas/Desktop/main2.py

Is possible to use pandas in this way? If so, what I'm doing wrong? If is not possible, how can I create a service using pandas?

Obs1: Pandas is installed in my machine, I'm not using virtual environment.

Obs2: If I execute the script with python3 main2.py, works normally with pandas.

Obs3: If I type which python3 in my prompt, shows the path configured in my_service.service.

在Linux服务上无法导入pandas库。

答案1

得分: 2

我发现我可以在我的.service文件中设置用户。我以以下格式设置了我的用户:

my_service.service:

[Unit]
Description=示例
After=network.target

[Service]
User=你当前的用户
ExecStart=/usr/bin/python3 /home/silas/Desktop/main2.py

[Install]
WantedBy=default.target

然后我使用了以下命令:

sudo systemctl restart my_service.service

该服务与pandas一起工作。

英文:

I discovered that I can set the user in my .service file. I set my user in this format:

my_service.service:

[Unit]
Description=Example
After=network.target

[Service]
User=your_current_user
ExecStart=/usr/bin/python3 /home/silas/Desktop/main2.py

[Install]
WantedBy=default.target

Then I used the command:

sudo systemctl restart my_service.service

The service worked with pandas.

答案2

得分: 2

你也可以将一个systemd服务运行在用户级别,将其放置在$XDG_CONFIG_HOME/systemd/user目录下,并使用--user标志启动该服务。对于我来说,$XDG_CONFIG_HOME~/.config

systemctl enable --now --user my_service.service

从那里开始,你需要在任何操作上都使用--user标志,比如检查statusdisablestop等。

英文:

You can also run a systemd service on the user level by putting it in $XDG_CONFIG_HOME/systemd/user and start the service with the --user flag. ($XDG_CONFIG_HOME for me is ~/.config)

systemctl enable --now --user my_service.service

You would have to use the --user flag on anything for it from there, like checking the status or disable or stop, etc

答案3

得分: 1

除了答案(只是一个附注)。

我们可以检查Python搜索模块的路径列表:

import logging

logging.basicConfig(
	filename='/path/to/my_service.log',
	level=logging.DEBUG,
	filemode='a')
logging.debug('Importing pandas')
try:
	import pandas
except Exception as e:
	logging.error('Failed to import pandas', exc_info=True)
	logging.debug('sys.path=[\n'+"\n".join(sys.path)+'\n]')
else:
	logging.debug('Succesfully imported pandas')

我猜Pandas是以pip install --user pandas的方式安装在用户文件夹中的。为了检查这一点,我们可以在REPL中运行:

import pandas; print(pandas.__file__)   # 在这种情况下可能在/home/silas/.local/lib/python3/site-packages/pandas中的某个位置

当运行服务时,Python将由root用户启动。因此,sys.path将被配置为忽略您的本地site-packages。可以手动添加路径,例如sys.path.append(your_pandas_path),但这很难是一个好决定。在服务中使用User=your_current_user是正确的选择。

英文:

In addition to the answer (just a side note).

We can check the list of paths, where python is searching for modules:

import logging

logging.basicConfig(
	filename='/path/to/my_service.log',
	level=logging.DEBUG,
	filemode='a')
logging.debug('Importing pandas')
try:
	import pandas
except Exception as e:
	logging.error('Failed to import pandas', exc_info=True)
	logging.debug('sys.path=[\n'+"\n".join(sys.path)+'\n]')
else:
	logging.debug('Succesfully imported pandas')

I guess that Pandas was installed like pip install --user pandas in a user folder. To check this we can run in REPL:

import pandas; print(pandas.__file__)   # maybe somewhere in /home/silas/.local/lib/python3/site-packages/pandas in this case

When running a service, python will be started by a root user. So sys.path will be configured ignoring your local site-packeges. It's possible to add the path manually like sys.path.append(your_pandas_path) but hardly it's a good decision. User=your_current_user in a service is the right choice.

huangapple
  • 本文由 发表于 2023年8月9日 07:02:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76863644.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定