Package: lc-sqlalchemy-dbutils
sqlalchemy-dbutils-pyOverviewSQLAlchemyhas two high-level components: Core and ORM. Core provides (not surprisingly)
the core functionality of SQLAlchemy's SQL abstraction layer. The ORM ("Object-Relational Mapper") component offers
the ability to map between Python and database types.sqlalchemy-dbutils-pyoffers a number of utilities built upon
the ORM component, including:Views and materialized views as regular database tables (viewmodule)Default types for common database engines (schemamodule)Database connection/session management (managermodule)InstallationInstall from PyPi (preferred method)pipinstalllc-sqlalchemy-dbutilsInstall from GitHub with Pippipinstallgit+https://github.com/libcommon/sqlalchemy-dbutils-py.git@vx.x.x#egg=lc_sqlalchemy_dbutilswherex.x.xis the version you want to download.Install by Manual DownloadTo download the source distribution and/or wheel files, navigate tohttps://github.com/libcommon/sqlalchemy-dbutils-py/tree/releases/vx.x.x/dist, wherex.x.xis the version you want to install,
and download either via the UI or with a tool like wget. Then to install run:pipinstall<downloadedfile>Donotchange the name of the file after downloading, as Pip requires a specific naming convention for installation files.Dependenciessqlalchemy-dbutils-pydepends on, and is designed to work with,SQLAlchemy. Only Python
versions >= 3.6 are officially supported.Getting StartedViewsTheviewmodule exposes a function,create_view, for creating (materialized) views that act like ORM tables.fromsqlalchemyimportColumn,Integer,Textfromsqlalchemy.ext.declarativeimportdeclarative_basefromsqlalchemy.sqlimportselectfromlc_sqlalchemy_dbutils.viewimportcreate_viewBaseTable=declarative_base()classUser(BaseTable):id=Column(Integer,primary_key=True)name=Column(Text,nullable=False)email_address=Column(Text,nullable=False)# Creates view named "vuser_names" as "SELECT id, name FROM user"UserNames=create_view("vuser_names",select([User.id,User.name]),BaseTable.metadata)TheUserNamestype, which points to thevuser_namesview in the database, can be used like any other ORM table class.
For Postgres databases, thematerializedparameter tocreate_viewcan be set toTrueto make aMATERIALIZED VIEW. For
more information about the difference from a standard SQL view, seehttps://www.postgresql.org/docs/current/rules-materializedviews.html.Database TypesTheschemamodule defines a type to generate database expressions for default datetime/timestamp values.
A common database design pattern is to use datetime/timestamp columns to track when records are created and/or modified.
TheTimestampDefaultExpressiontype can be used with theserver_defaultparameter to theColumn constructor.fromsqlalchemyimportColumn,Integer,Text,TIMESTAMPfromsqlalchemy.ext.declarativeimportdeclarative_basefromsqlalchemy.sqlimportselectfromlc_sqlalchemy_dbutils.schemaimportTimestampDefaultExpressionBaseTable=declarative_base()classUser(BaseTable):id=Column(Integer,primary_key=True)name=Column(Text,nullable=False)email_address=Column(Text,nullable=False)created_at=Column(TIMESTAMP(True),nullable=False,server_default=TimestampDefaultExpression())Note the use ofTIMESTAMP(True), as theTimestampDefaultExpressiontype will attempt to generate an expression to
retrieve a UTC timestamp in all cases.Database Connection ManagementThemanagermodule exposes a class,DBManager, for managing database connections and sessions with higher-level methods.
Simply create an instance ofDBManagerwith an RFC-1738 compliant connection URL, and with that instance you can
connect to the datbase server, generate ORMSessions,
build queries using ORM objects, add and remove records from the active session, and commit or rollback transactions.importsysfromsqlalchemyimportColumn,Integer,Textfromsqlalchemy.ext.declarativeimportdeclarative_basefromsqlalchemy.sqlimportselectfromlc_sqlalchemy_dbutils.managerimportDBManagerBaseTable=declarative_base()classUser(BaseTable):id=Column(Integer,primary_key=True)name=Column(Text,nullable=False)email_address=Column(Text,nullable=False)defmain()->int:# Get commandline argumentsconfig_path_str=sys.argv[1]name_filter=sys.argv[2]# Create DB manager from connection URL in config file# and attach MetaData object from BaseTablemanager=(DBManager.from_file(config_path_str).with_metadata(BaseTable.metadata))# Connect to database (but don't generate a session yet)manager.connect()# NOTE: connect() is effectively equivalent to# manager.create_engine().create_session_factory(), but it can also# call the bootstrap_db() method to create all tables in the database.# The caveat with using connect() is that you cannot pass specific kwargs# to create_engine() or create_session_factory().# Create an active database Sessionmanager.gen_session()# Query the "user" table for the name specified on the commandlinematching_user=manager.query(User,name=name_filter).first()ifmatching_user:print("Found matching user with name{}(ID:{})",name_filter,matching_user.id)else:print("Did not find matching user with name{}",name_filter)# Close active session and dispose of database engine (which closes all connections)# NOTE: close_engine() automatically calls close_session()manager.close_engine()return0if__name__=="__main__":main()The script above will read the database connection URL from the provided config filepath, connect to the database
and generate aSession, run a query to find the firstUserrecord wherenamematches the provided name filter,
and print the results. This is just an (heavily commented) example to show easy session management can be with theDBManagerclass.Contributing/SuggestionsContributions and suggestions are welcome! To make a feature request, report a bug, or otherwise comment on existing
functionality, please file an issue. For contributions please submit a PR, but make sure to lint, type-check, and test
your code before doing so. Thanks in advance!