On Fri, 11 Nov 2022 21:20:10 -0500, DFS <nos...@dfs.com> declaimed the
following:

>Yeah, I don't know why cursor.description doesn't work with SQLite; all 
>their columns are basically varchars.
>
        If you read PEP 249 (the general DB-API), everything except column name
and data type code are optional. And the documentation for the sqlite3
module explicitly states that it only provides the column name, not even
type code.
 
>
>The query is literally any SELECT, any type of data, including SELECT *. 
>  The reason it works with SELECT * is the cursor.description against 
>SQLite DOES give the column names:
>
>select * from timezone;
>print(cur.description)
>(
>('TIMEZONE',     None, None, None, None, None, None),
>('TIMEZONEDESC', None, None, None, None, None, None),
>('UTC_OFFSET',   None, None, None, None, None, None)
>)
>
>(I lined up the data)
>
>

        Consider (table definition first)

CREATE TABLE Game (
        ID INTEGER PRIMARY KEY NOT NULL,
        Variant VARCHAR(64) NOT NULL,
        Num_of_Decks INTEGER DEFAULT 1 NOT NULL,
        Cards_in_Deck INTEGER DEFAULT 52 NOT NULL,
        Num_Tableau_Cards INTEGER NOT NULL,
        Num_Reserve_Cards INTEGER  
                GENERATED ALWAYS 
                AS ((Num_of_Decks * Cards_in_Deck) - Num_Tableau_Cards) STORED,
        Foundation_Value INTEGER DEFAULT 1 NOT NULL,
        Tableau_Value INTEGER DEFAULT -1 NOT NULL,
        Reserve_Value INTEGER DEFAULT -2 NOT NULL
);
CREATE UNIQUE INDEX idx_Variant ON Game (Variant);

followed by a session retrieving three columns...

>>> import sqlite3 as db
>>> con = 
>>> db.connect("c:/users/wulfraed/documents/.localdatabases/solitaire-sqlite/solitaire.db")
>>> cur = con.cursor()
>>> cur.execute("""select max(length(variant)), max(length(cards_in_deck)),
...             max(length(num_reserve_cards)) from Game""")
<sqlite3.Cursor object at 0x00000246D91E3F80>
>>> widths = cur.fetchall()
>>> widths
[(16, 2, 2)]
>>> 
>>> widths[0]
(16, 2, 2)
>>> pformat = [f'%{w}s' for w in widths[0] ]
>>> pformat
['%16s', '%2s', '%2s']
>>> pformat = "\t".join(pformat)
>>> pformat
'%16s\t%2s\t%2s'
>>> for row in cur.fetchall():
...     print(pformat % row)
...     
 Klondike draw-3        52      24
Perpetual Motion        52      52
 Klondike draw-1        52      24
>>> 

        Granted, this will NOT work with "select *" unless one does the select
*/fetchall first, AND extracts the names from the cursor description --
then run a loop to create the select max(length(col)), ... statement (which
is why I state the fetchall step, as unless one creates a second cursor,
the latter select will wipe out any unfetched data from the first).

        It lets SQLite do the work of determining the max width occupied by
each column, rather than some complicated Python loop.



-- 
        Wulfraed                 Dennis Lee Bieber         AF6VN
        wlfr...@ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/
-- 
https://mail.python.org/mailman/listinfo/python-list

Reply via email to