element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      • Japan
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Vietnam
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Pi IoT
  • Challenges & Projects
  • Design Challenges
  • Pi IoT
  • More
  • Cancel
Pi IoT
Blog [Pi IoT] HangarControl #8, Database? What's a Database?
  • Blog
  • Forum
  • Documents
  • Polls
  • Files
  • Events
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: rhavourd
  • Date Created: 28 Aug 2016 1:24 PM Date Created
  • Views 647 views
  • Likes 0 likes
  • Comments 0 comments
Related
Recommended

[Pi IoT] HangarControl #8, Database? What's a Database?

rhavourd
rhavourd
28 Aug 2016

Don't Over Complicate It

Oftentimes it seems that as programmers, or anything else for that matter, we get caught up in a particular pattern for doing things. One that I see quite often is the use of SQL databases in various projects. The "kids" these days are introduced to SQL as a primer for programming and can't think how to handle persistence without it. To show that life can exist without a formal database, HangarControl is being written using some very simple mechanisms for creating, reading, and updating information.

 

The User Record

In a future episode, I will discuss the Flask-Login module. Flask-Login is a set of helper routines to streamline user session management. As it is written in Python, it expects that your users can be accessed as "User" objects. One might be tempted to just fire up SQLAlchemy (SQLAlchemy - The Database Toolkit for Python ) and start creating a database. Instead, we're going to create a class that provides everything needed without the overhead of a database manager.

 

According to the documentation, Flask-Login requires the following properties and methods:

is_authenticatedThis property should return True if the user is authenticated, i.e. they have provided valid credentials. (Only authenticated users will fulfill the criteria of login_required.)
is_activeThis property should return True if this is an active user - in addition to being authenticated, they also have activated their account, not been suspended, or any condition your application has for rejecting an account. Inactive accounts may not log in (without being forced of course).
is_anonymousThis property should return True if this is an anonymous user. (Actual users should return False instead.)
get_id()This method must return a unicode that uniquely identifies this user, and can be used to load the user from the user_loader callback. Note that this must be a unicode - if the ID is natively an int or some other type, you will need to convert it to unicode.

 

Define a User Record

We can easily provide this directly from our favorite text editor. I have broken up the various portions for discussion purposes. Trust that they are all that makes up the 'user.py' file.

# Get a template object for our User record.
from flask_login import UserMixin

class User(UserMixin):
    # This is an array that will be shared across all instances of this class
    users = []
    
    # This method is automatically called when a new instance of User is created.
    # Notice at the end where the *class* User appends this new instance to our
    # users list. Just think "SQL insert".
    def __init__(self, username, acctnum, password=None, fullname=None, active=True):
        self.username = username
        self.acctnum = acctnum
        self.fullname = fullname
        self.password = password
        self.active = active
        User.users.append(self)

 

Here is something that I recommend you do that just makes your (debugging) liffe so much easier: Create a method for rendering your object in a human readable form!

    # Any class that you create should implement __repr__. This provides a 
    # convenient method to display a human readable representation of your object.
    def __repr__(self):
      return "<User username:%s acctnum:%s password:%s fullname:%s>" % \
        (self.username, self.acctnum, self.password, self.fullname)

 

If you've done any work with Python, the above pattern is pretty familiar. Next we implement the methods that Flask-Login is expecting from us.

    # These are required by the Flask-Login module        
    def is_active(self):
        return self.active

    def is_anonymous(self):
        return False

    def is_authenticated(self):
        return True
        
    def get_id(self):
        return self.username

 

The final portion of our User class is the piece that makes all this "what's a database anyway?" talk complete. Here we are simply defining a mechanism or language, if you will, to query User records in a structured way. Ooh, see what I did there? (Okay, "... structured ... query ... language ...") That's okay, my kids didn't think it was funny either.

    # The @classmethod decorator (think "modifier") makes the method definition
    # available by this syntax: "User.find_by_attr(...)". The important concept
    # is that this method isn't used by individual 'user records', rather the 
    # collection of all 'user' records.
    @classmethod
    def find_by_attr(cls,key,target):
      for user in User.users:
        if getattr(user,key) == target:
          return user
          break
      else:
        return None
        
    @classmethod
    def find_by_username(cls,target):
      return cls.find_by_attr('username',target)

 

Working With User Records

Now that we have an implementation of a User, let's take a look at how it will be utilized.

$ python
>>> from lib.user import User
>>> User('admin', 0, 'pilot', 'Administrator')
<User username:admin acctnum:0 password:pilot fullname:Administrator>
>>> User('pilot', 142, 'secret', 'Ima Pilot')
<User username:pilot acctnum:142 password:secret fullname:Ima Pilot>
>>> User.users
[ <User username:admin acctnum:0 password:pilot fullname:Administrator>,
  <User username:pilot acctnum:142 password:secret fullname:Ima Pilot>]
>>> User.find_by_username('admin')
<User username:admin acctnum:0 password:pilot fullname:Administrator>
>>> User.find_by_username('whodat')
>>> User.find_by_username('whodat') == None
True

 

Users, Nice and Tidy

In just a couple dozen lines of code, we have implemented everything that we need for our user management. Understandably, it does not handle the complexities of a frequently changing population. But for the sake of this project, the user population is very stable and the creation and management of pilots is handled by another application and HangarControl only gets a list of pilots when there has been a change.

 

I hope you have found this useful and, in the future, aren't afraid to "go naked" and skip the SQL database!

 

Rick

  • Sign in to reply
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube