Giter Site home page Giter Site logo

python-p3-defining-schema-with-sqlalchemy's Introduction

Defining a Schema with SQLAlchemy ORM

Learning Goals

  • Use an external library to simplify tasks from earlier ORM lessons.

Key Vocab

  • Schema: the blueprint of a database. Describes how data relates to other data in tables, columns, and relationships between them.
  • Persist: save a schema in a database.
  • Engine: a Python object that translates SQL to Python and vice-versa.
  • Session: a Python object that uses an engine to allow us to programmatically interact with a database.
  • Transaction: a strategy for executing database statements such that the group succeeds or fails as a unit.
  • Migration: the process of moving data from one or more databases to one or more target databases.

Introduction

By now you are familiar with the concept of an ORM, an Object-Relational Mapper. While building your own ORM for a single class is a great way to learn about how object-oriented programming languages commonly interact with a database, imagine you had many more classes. Having to test and maintain custom code to build database connectivity for each project we work on would divert our attention from what we really want to be focusing on: making cool stuff.

To save themselves and others this headache, a team of developers built the SQLAlchemy Python package.

In this lesson, we'll read about how to have SQLAlchemy link our Python classes with a database table. There's code in the lib/sqlalchemy_sandbox.py file set up so you can follow along with the examples below. Fork and clone this lesson if you'd like to code along.

Note: You'll never write all the code for your SQLAlchemy applications in one file like we're doing here β€” the setup here is kept intentionally as simple as possible so you can see everything in one place. Soon, we'll cover a more realistic SQLAlchemy file structure.

As you work through this section, it's highly recommended that you also take some time to read through the SQLAlchemy guides. There's a lot more that SQLAlchemy can do than we'll be able to cover, so you're sure to discover a lot of fun new things by checking out the documentation!


SQLAlchemy ORM

SQLAlchemy is a Python library, meaning we get access to many classes and methods when we install it in our environment. There are two modes in which you can use SQLAlchemy: SQLAlchemy Core and SQLAlchemy ORM. SQLAlchemy ORM better suits our needs here, but you may encounter SQLAlchemy Core later on in your career.

We've already configured your virtual environment to include SQLAlchemy. Simply run pipenv install to download sqlalchemy and some other helpful libraries, then pipenv shell to enter your virtual environment.


Defining Tables via SQLAlchemy ORM

Creating tables with SQLAlchemy ORM requires classes with four key traits:

  1. Inheritance from a declarative_base object.
  2. A __tablename__ class attribute.
  3. One or more Columns as class attributes.
  4. A Column specified to be the table's primary key.

Let's take a look at a class to define a students table:

# lib/sqlalchemy_sandbox.py
from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Student(Base):
    __tablename__ = 'students'

    id = Column(Integer(), primary_key=True)
    name = Column(String())

The declarative_base combines a container for table metadata as well as a group of methods that act as mappers between Python and our SQL database. Inheritance from Base, a declarative_base object, allows us to avoid rewriting code.

Is Base a parent or child object?

A parent.

Just as in real life, children in Python inherit from their parents.


The __tablename__ attribute will eventually be used as the name of our SQL database table. The table's columns are identified using Column objects as attributes- the optional primary_key argument tells SQLAlchemy that id will be the primary key for the students table.

This type of class is called a data model, or model.

Persisting the Schema

We have all of the data we need to generate a database table, but it won't happen as soon as we save our module. We need to execute a series of Python statements to do persist our schema. You can do this from the Python shell, but we will be using a script for this exercise.

# lib/sqlalchemy_sandbox.py

#!/usr/bin/env python3

# imports
from sqlalchemy import create_engine

# data models

if __name__ == '__main__':
    engine = create_engine('sqlite:///students.db')
    Base.metadata.create_all(engine)

Now run chmod +x lib/sqlalchemy_sandbox.py to make the script executable. Run lib/sqlalchemy_sandbox.py from your Pipenv shell and you should see that a students.db has popped up with a students table.

Just as with using the sqlite3 Python module on its own, we need to start by creating a connection to the database. The engine is "home base" for the database- everything on the database side and the Python side must pass through the engine for the process to count. Here, we're pointing to a local sqlite file where our tables will be created.

The create_all() command on the next line tells the engine that any models that were created using Base as a parent should be used to create tables. if you open students.db in VSCode, you should see that a table exists with two columns: id and name.


Conclusion

You should know now how to define and persist a simple schema using SQLAlchemy. In the next lesson, we will explore how to create, read, update, and delete records with SQLAlchemy ORM.


Solution Code

# lib/sqlalchemy_sandbox.py

from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Student(Base):
    __tablename__ = 'students'

    id = Column(Integer(), primary_key=True)
    name = Column(String())

if __name__ == '__main__':
    engine = create_engine('sqlite:///students.db')
    Base.metadata.create_all(engine)

Resources

python-p3-defining-schema-with-sqlalchemy's People

Contributors

jlboba avatar lizbur10 avatar professor-ben avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

python-p3-defining-schema-with-sqlalchemy's Issues

Not Able To Create DB Inside A Directory

Canvas Link

https://learning.flatironschool.com/courses/6049/assignments/205983?module_item_id=472696

Concern

Went through the code with Ben in sqlalchemy_sandbox.py. My system allows me to create a database file at the root level but not inside an inner directory (in our case, from inside the lib folder, creating the database file inside of an existing db directory.

Specifically, this correctly creates the database when you run the sandbox file: engine = create_engine('sqlite:///my_database.db') but this does not: engine = create_engine('sqlite:///db/my_database.db')

Additional Context

No response

Suggested Changes

No response

Gramatical Errors

Canvas Link

https://learning.flatironschool.com/courses/6274/assignments/236177?module_item_id=554160

Concern

  1. in the following paragraph under Persisting the Schema, remove the word "do":
    We have all of the data we need to generate a database table, but it won't happen as soon as we save our module. We need to execute a series of Python statements to remove - do- remove persist our schema. You can do this from the Python shell, but we will be using a script for this exercise.

Additional Context

No response

Suggested Changes

No response

packages

Canvas Link

https://learning.flatironschool.com/courses/6049/assignments/205983?module_item_id=472696

Concern

pytest will not run without pytest = "x" included in [packages] section of Pipfile OR If pipenv installed -d is run to assure the development packages are installed. I don’t believe this flag was covered in previous labs.

This issue persists in all of the SQLAlchemy labs.

Additional Context

No response

Suggested Changes

Add a reminder to run pipenv installed -d to ensure all dependencies are installed.

How is the Script Working?

Canvas Link

https://learning.flatironschool.com/courses/6049/assignments/205983?module_item_id=472696

Concern

There might be a few missing pieces in this lesson when discussing the script at the end:

Will the script still be called from the module that's importing sqlalchemy_sandbox.py? Or will adding if __name__ = '__main__' simply prevent it being run from other modules at all?

Is the rest of the code in this file also going to run before any other code in a module that imports this file?

What's the utility of making this file a script? Is that commonly done?

I can see students being confused as to why this material is included in this lesson - it's relevance it's immediately apparent.

Additional Context

No response

Suggested Changes

No response

Missing db directory and persisting the schema section

Canvas Link

https://learning.flatironschool.com/courses/6049/assignments/205983?module_item_id=472696

Concern

Persisting the Schema:
It's not super clear where the script is supposed to go. Additionally, there is no db directory, and I needed to make one in order for the script to work.

The engine explanation is a little confusing.
Tying in some explicit information about the create_engine import and its argument should help a bit.

Additional Context

No response

Suggested Changes

Add in the db folder and add some explicit information about create_engine

Possible sqlalchemy version issue

Canvas Link

https://learning.flatironschool.com/courses/6049/assignments/205983?module_item_id=472696

Concern

After running pipenv install and pipenv shell, the sqlalchemy imports in the sqlalchemy_sandbox.py file have yellow squiggles and "Import "sqlalchemy" could not be resolved from source" message.
Screen Shot 2023-01-27 at 5 57 03 PM

I continue with the code along, it did work correctly it seems but when running the "lib/sqlalchemy_sandbox.py" command the following warning was given:
Screen Shot 2023-01-27 at 5 58 46 PM

It looks like sqlalchemy just released version 2.0 yesterday so I am wondering if that is what this issue is related to.

Additional Context

https://www.sqlalchemy.org/blog/2023/01/26/sqlalchemy-2.0.0-released/

Suggested Changes

No response

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.