How to refer to columns whose names begin with a number when autoloading?

10 views
Skip to first unread message

Rob Rosenfeld

unread,
Apr 12, 2021, 12:29:47 AM4/12/21
to sqlal...@googlegroups.com
Hi All,

I'm using SQLAlchemy to access a legacy MSSQL database.   I'm using the autoload feature to load the schema from the database.

In this example I'd like to read data out of the column named "1st_period" in the database.   The following query shows the SQL I'd need.  But trying to access a property named "1st_period" yields a SyntaxError

Thanks,
Rob

SELECT TOP 10 [1st_period] FROM Students;

class Student(Model):
__table__ = Table("Students", metadata, autoload=True, autoload_with=engine)

@property
def first_period(self):
return self.1st_period
    

Richard Damon

unread,
Apr 12, 2021, 6:55:07 AM4/12/21
to sqlal...@googlegroups.com
On 4/12/21 12:29 AM, Rob Rosenfeld wrote:
> Hi All,
>
> I'm using SQLAlchemy to access a legacy MSSQL database.   I'm using
> the autoload feature to load the schema from the database.
>
> In this example I'd like to read data out of the column named
> "1st_period" in the database.   The following query shows the SQL I'd
> need.  But trying to access a property named "1st_period" yields a
> SyntaxError
>
> Thanks,
> Rob
>
> SELECTTOP 10[1st_period] FROM Students;
>
> class Student(Model):
> __table__ = Table("Students", metadata, autoload=True,
> autoload_with=engine)
>
> @property
> def first_period(self):
> return self.1st_period


Have you tried using getattr? That might work (if SQLAlchemy isn't doing
something to quote the name to make a valid version.

getattr(self, '1st_period') would be the equivalent of self.1st_period,
but not have the name parsed by Python.

--
Richard Damon

r...@rosenfeld.to

unread,
Apr 12, 2021, 10:35:47 PM4/12/21
to sqlalchemy
Yep.  That seems fine.  Thanks.  

SQLAlchemy doesn't escape or quote the name.   I checked using

    inspection = inspect(Student)
    return [c_attr.key for c_attr in inspection.mapper.column_attrs]

Mike Bayer

unread,
Apr 13, 2021, 12:17:59 AM4/13/21
to noreply-spamdigest via sqlalchemy
besides the idea of using getattr(), as these are object attributes it's probably a good idea to name them differently from those columns.  See the docs at https://docs.sqlalchemy.org/en/14/orm/mapping_columns.html#naming-columns-distinctly-from-attribute-names for strategies on how to achieve this.
--
SQLAlchemy -
The Python SQL Toolkit and Object Relational Mapper
 
 
To post example code, please provide an MCVE: Minimal, Complete, and Verifiable Example. See http://stackoverflow.com/help/mcve for a full description.
---
You received this message because you are subscribed to the Google Groups "sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+...@googlegroups.com.

r...@rosenfeld.to

unread,
Apr 13, 2021, 8:48:47 AM4/13/21
to sqlalchemy
Thanks for the documentation.  Sorry, but I'm not certain how to apply that in my case.  Since I am mapping to an existing table, how could I reference the object attribute with an illegal name in Python?   Do I combine getattr with the documentation as below?

    class Student(Model):
        __table__ = Table("Students", metadata, autoload=True, autoload_with=engine)
        first_period = getattr(__table__.c, "1st_period")

Thanks,
Rob

Mike Bayer

unread,
Apr 13, 2021, 9:46:34 AM4/13/21
to noreply-spamdigest via sqlalchemy
the next section at https://docs.sqlalchemy.org/en/14/orm/mapping_columns.html#automating-column-naming-schemes-from-reflected-tables shows how to automate intercepting of reflected columns, so you could do this:

from sqlalchemy import event

@event.listens_for(metadata, "column_reflect")
def column_reflect(inspector, table, column_info):
    entries = {
        "1st": "first",
        "2nd": "second",
        "3rd": "third",
        "4th": "fourth"
    }
    for prefix in entries:
        if prefix in column["name"]:
            column["key"] = column["name"].replace(prefix, entries[prefix])
            break


class Student(Model):
    __table__ = Table("Students", metadata, autoload=True, autoload_with=engine)




r...@rosenfeld.to

unread,
Apr 14, 2021, 11:44:46 AM4/14/21
to sqlalchemy
Thanks.   That worked, too.
Reply all
Reply to author
Forward
0 new messages