Hello I'm working on mobile application with kivy and python. Everything was fine until I wanted to use sqlite3. Here is my directory structure:
application
├───main.py
├───core
│ └───__pycache__
| ├───calendar_screen.py
| ├───children.py
| ├───menu.py
| ├───screen_manager.py
| ├───settings.py
| └───vaccination.py
├───database
| ├───vaccination_calendar.db
| ├───vaccination_calendar.py
│ └───__pycache__
├───fonts
│ └───static
│ ├───OpenSans
│ ├───OpenSans_Condensed
│ └───OpenSans_SemiCondensed
├───images
│ └───icons
├───layouts
| ├───calendar.kv
| ├───children.kv
| ├───menu.kv
| ├───screen_manager.kv
| ├───settings.kv
| └───vaccination.kv
└───__pycache__
Relevent code main.py
from kivymd.app import MDApp
from core.screen_manager import WindowManager
class VaccinationCalendarApp(MDApp):
def build(self):
self.theme_cls.primary_palette = "Green"
return WindowManager()
if __name__ == "__main__":
VaccinationCalendarApp().run()
screen_manager.py
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager
Builder.load_file("layouts/screen_manager.kv")
class WindowManager(ScreenManager):
pass
screen_manager.kv
#: import Menu core.menu
#: import Calendar core.calendar_screen
#: import Children core.children
#: import Vaccination core.vaccination
#: import Settings core.settings
<WindowManager>:
Menu:
Calendar:
Children:
Vaccination:
SettingsScreen:
children.py
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen
from kivymd.uix.list import OneLineAvatarIconListItem, IconLeftWidget
from application.database.vaccination_calendar import get_children
Builder.load_file("layouts/children.kv")
class Children(Screen):
pass
vaccination_calendar.py
import sqlite3
def get_children():
statement = "select * from children"
with sqlite3.connect("vaccination_calendar.db") as conn:
cursor = conn.cursor()
cursor.execute(statement)
children_list = [{"id": child[0], "name": child[1], "birth_date": child[2], "days_age": child[3]}
for child in cursor.fetchall()]
conn.commit()
return children_list
Everything was fine until this line in children.py: from application.database.vaccination_calendar import get_children. After adding this line I get AttributeError with traceback:
Traceback (most recent call last):
File "C:\Users\przem\PycharmProjects\vaccination_calendar\application\main.py", line 3, in <module>
File "C:\Users\przem\PycharmProjects\vaccination_calendar\env\lib\site-packages\kivy\lang\builder.py", line 305, in load_file
return self.load_string(data, **kwargs)
File "C:\Users\przem\PycharmProjects\vaccination_calendar\env\lib\site-packages\kivy\lang\builder.py", line 372, in load_string
parser = Parser(content=string, filename=fn)
File "C:\Users\przem\PycharmProjects\vaccination_calendar\env\lib\site-packages\kivy\lang\parser.py", line 483, in __init__
self.parse(content)
File "C:\Users\przem\PycharmProjects\vaccination_calendar\env\lib\site-packages\kivy\lang\parser.py", line 590, in parse
self.execute_directives()
File "C:\Users\przem\PycharmProjects\vaccination_calendar\env\lib\site-packages\kivy\lang\parser.py", line 559, in execute_directives
mod = getattr(mod, part)
AttributeError: module 'core' has no attribute 'children'
I suspect that it is something wrong with circular dependency but tbh i can't see anything wrong with this. File i past here are in imported order starting from main.py Any idea what is wrong?
I tried to import vaccination_calendar.py by method in children.py but after that i get ModuleNotFoundError I also tried to import in to main.py and there it works but then i don't see any idea to use vaccination_calendar.py in children screen.
CodePudding user response:
The error can be found in the following line:
from application.database.vaccination_calendar import get_children
I assume you run main.py
. When you do so ./application
gets added to sys.path
. That is why Python will never be able to resolve a module path like application.some.module_path
, instead it should only be the some.module_path
part.
The error message is pretty cryptic, but that is the result of Kivy trying to parse the screen_manager.kv
file. In the process of doing so it finds this wrong import and raises an error deep inside the Kivy library (cause it tries to parse a .kv
file) instead of directly telling you what exactly is wrong.
CodePudding user response:
I find a solution to this problem. I don't know where exactly was the problem but I change the way I import vaccination_calendar. I change this:
from application.database.vaccination_calendar import get_children
To this:
sys.path.append('database')
import vaccination_calendar
Pycharm still see a problem but it works for me. Maybe someone can use it.