Using list as a data type in a column (SQLAlchemy)

Question:

I want to store a list of rss feed urls in an sqlite db. I’m using SQLAlchemy and was wondering how to store these. I can’t seem to find any documentation about lists, and was wondering if this was legal for a column:
Column(‘rss_feed_urls’, List)

Or is there an array type that I could use?

Asked By: Chris

||

Answers:

There is normally no list among SQL database column data types.

One way to store a list as a column value is to convert that list to a string, that would map to database data type varchar.

Another way is to convert the list to a serialized binary representation (using pickle library, for example) and store the value as a database value of type blob.

Answered By: Maxim Egorushkin

If you really must you could use the PickleType. But what you probably want is another table (which consists of a list of rows, right?). Just create a table to hold your RSS feeds:

class RssFeed(Base):
    __tablename__ = 'rssfeeds'
    id = Column(Integer, primary_key=True)
    url = Column(String)

Add new urls:

feed = RssFeed(url='http://url/for/feed')
session.add(feed)

Retrieve your list of urls:

session.query(RssFeed).all()

Find a specific feed by index:

session.query(RssFeed).get(1)

I’d recommend SQLAlchemy’s Object Relational Tutorial.

Answered By: Zach Kelling

If you are using a PostgreSQL database, you can use the SQL Alchemy type ARRAY for that. Note that it is a typed Array.

class sqlalchemy.types.ARRAY(item_type, as_tuple=False, dimensions=None, zero_indexes=False)

You can use MutableList from sqlalchemy

from sqlalchemy.ext.mutable import MutableList
from sqlalchemy import pickleType
import logging # not necessary, for logging purpose only

my_list_column_field = Column(MutableList.as_mutable(PickleType),
                                    default=[])

# now you can do common operations in this list. e.g:

# append to the list (just like python)
my_list_column_field = my_list_column_field + [any_data_type]

# and don't forget to commit your changes
try:
   db.commit()
except SQLAlchemyError as e:
   db.rollback()
   logging.error("Failed to Commit because of {error}. Doing Rollback".format(error=e))

If you simply use PickleType, you won’t be able to modify that list after the first insert. To modify later we need MutableList. You can also use Set, Dict like this using MutableSet, MutableDict.

There is another less obvious way though. To save as String by json.dumps(my_list) and then while retrieving just do json.loads(my_column). But it will require you to set the data in a key-value format and seems a bit in-efficient compared to the previous solution.

Answered By: Amin Pial
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.