Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign upbpo-39170: Sqlite3 row_factory for attribute access: sqlite3.NamedRow #17768
+723
−20
Conversation
9 commits
Sep 8, 2019
added + Creates object in sqlite3 + row_factory works + Get by index + Get by dict + Case insensitive + Underscore acceptable replacement for space or dash + AttributeError works + IndexError works
Test both the cursor descriptor and data.
Does the cursor.execute().fetchone() effect the general shape of the data? Add testing which only covers object creation and access.
+ Faster + Remove case insensitive
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
jidn commentedDec 31, 2019
•
edited
Currently, sqlite3 returns rows by tuple or
sqlite3.Row
for dict-style, index access. I constantly find myself wanting attribute access likenamedtuple
for rows. I find attribute access cleanerwithout the brackets and quoting field names. However, unlike previous discussions (https://bugs.python.org/issue13299), I don't want to use the
namedtuple
object. I appreciate the simple API and minimal memory consumption of sqlite3.Row and used it as my guide in creatingsqlite3.NamedRow
to allow access by index and attribute.Why a new object instead of adding attribute access to the existing sqlite3.Row?
There is an existing member method
keys
and any table with the field "keys" would cause a hard to debug, easily avoidable, collision.Features
len
and operatorcontains
.Examples
How sqlite3.NamedRow differs from sqlite3.Row
The class only has class dunder methods to allow any valid attribute name. When the column name would be an invalid attribute name, you have two options: either use the SQL
AS
in the select statement or index by name.To get the field names, use the iterator
[x[0] for x in row]
or do the same from thecursor.description
.Name and dict access are no longer case-insensitive. There are four reasons for this.
row.name
,row.Name
, androw.NAME
are all the same it gives off the faint code smell of something wrong. When case-insensitively is needed and the query SELECT can not be modified, sqlite3.Row is still there.Timing Results
NamedRow is faster than
sqlite3.Row
for index-by-name access. Speed is not the focus. I just want to show that this is not any slower thansqlite3.Row
when dealing with thousands for results.I have published a graph and the methodology of my testing. In the worst case scenario, it is just as fast as sqlite3.Row without any extra memory.
For more information, see the post at https://jidn.com/posts/2019/10/namedrow-better-python-sqlite3-row-factory/
https://bugs.python.org/issue39170