# Code Structure and Multiple Files Let's stop for a second to think about how to structure the code, particularly in **large projects** with multiple files. ## Circular Imports The class `Hero` has a reference to the class `Team` internally. But the class `Team` also has a reference to the class `Hero`. So, if those two classes where in separate files and you tried to import the classes in each other's file directly, it would result in a **circular import**. π And Python will not be able to handle it and will throw an error. π¨ But we actually want to *mean* that **circular reference**, because in our code, we would be able to do crazy things like: ```Python hero.team.heroes[0].team.heroes[1].team.heroes[2].name ``` And that circular reference is what we are expressing with these **relationship attributes**, that: * A hero can have a team * That team can have a list of heroes * Each of those heroes can have a team * ...and so on. Let's see different strategies to **structure the code** accounting for this. ## Single Module for Models This is the simplest way. β¨ In this solution we are still using **multiple files**, for the `models`, for the `database`, and for the `app`. And we could have any **other files** necessary. But in this first case, all the models would live in a **single file**. The file structure of the project could be: ``` . βββ project βββ __init__.py βββ app.py βββ database.py βββ models.py ``` We have 3 **Python modules** (or files): * `app` * `database` * `models` And we also have an empty `__init__.py` file to make this project a "**Python package**" (a collection of Python modules). This way we can use **relative imports** in the `app.py` file/module, like: ```Python from .models import Hero, Team from .database import engine ``` We can use these relative imports because, for example, in the file `app.py` (the `app` module) Python knows that it is **part of our Python package** because it is in the same directory as the file `__init__.py`. And all the Python files on the same directory are part of the same Python package too. ### Models File You could put all the database Models in a single Python module (a single Python file), for example `models.py`: ```Python {!./docs_src/tutorial/code_structure/tutorial001/models.py!} ``` This way, you wouldn't have to deal with circular imports for other models. And then you could import the models from this file/module in any other file/module in your application. ### Database File Then you could put the code creating the **engine** and the function to create all the tables (if you are not using migrations) in another file `database.py`: ```Python {!./docs_src/tutorial/code_structure/tutorial001/database.py!} ``` This file would also be imported by your application code, to use the shared **engine** and to get and call the function `create_db_and_tables()`. ### Application File Finally, you could put the code to create the **app** in another file `app.py`: ```Python hl_lines="3-4" {!./docs_src/tutorial/code_structure/tutorial001/app.py!} ``` Here we import the models, the engine, and the function to create all the tables and then we can use them all internally. ### Order Matters Remember that [Order Matters](create-db-and-table.md#sqlmodel-metadata-order-matters){.internal-link target=_blank} when calling `SQLModel.metadata.create_all()`? The point of that section in the docs is that you have to import the module that has the models **before** calling `SQLModel.metadata.create_all()`. We are doing that here, we import the models in `app.py` and **after** that we create the database and tables, so we are fine and everything works correctly. π ### Run It in the Command Line Because now this is a larger project with a **Python package** and not a single Python file, we **cannot** call it just passing a single file name as we did before with: ```console $ python app.py ``` Now we have to tell Python that we want it to execute a *module* that is part of a package: ```console $ python -m project.app ``` The `-m` is to tell Python to call a *module*. And the next thing we pass is a string with `project.app`, that is the same format we would use in an **import**: ```Python import project.app ``` Then Python will execute that module *inside* of that package, and because Python is executing it directly, the same trick with the **main block** that we have in `app.py` will still work: ```Python if __name__ == '__main__': main() ``` So, the output would be: