6

I need to create a schema but it has a column called global, and when I try to write this, I got an error.

class User(BaseModel):

    id:int
    global:bool

I try to use another name, but gives another error when try to save in db.

mx0
  • 6,445
  • 12
  • 49
  • 54
Matheus
  • 139
  • 4
  • 13
  • 4
    `global` is a reserved keyword for a reason. Find another name. – esqew Jan 04 '22 at 20:36
  • 1
    Something like `is_global` would be more clear anyway. Why does it have to be called `global`? Surely there's a way to map python variable names to SQL column names without them needing to be identical. – Random Davis Jan 04 '22 at 20:38
  • 1
    Keep in mind that `global` may not be an invalid column name, but it is *syntactically* invalid in a `class` statement like this, so you would need to find another way to add the column to your model. – chepner Jan 04 '22 at 20:41
  • As an analogous example, something like `foo.global = 5` would be a syntax error, but `setattr(foo, "global", 5)` is perfectly legal. – chepner Jan 04 '22 at 20:41
  • i know that is a reserved keyword man (but i need to use the same name of tables column), because of that i made the question , but the solution given by mx0 work`s fine for me, thank you all guys. – Matheus Jan 05 '22 at 02:57
  • "Just use another name" is rather obtuse. Sometimes we need to parse data from external sources and APIs (e.g. webhooks sent to us) and we don't have any control over their naming conventions. – theberzi Nov 03 '22 at 09:29
  • What are the actual errors? Exact error message? – Peter Mortensen May 31 '23 at 18:16
  • @Theberzi But external data sources can, or at least _should_, never dictate **how you name your class attributes** (your local variables, effectively). Any data model that requires you to store an arbitrary piece of data under a **specific** arbitrary name is broken, that's an unworkable restriction, because all languages have _some_ syntax rules. Fortunately the pydantic designers provided an out that makes their (still ugly) model _slightly_ less broken, by allowing adjustments to the name mapping via `Config.fields`. – FeRD Jul 03 '23 at 08:33
  • (And Python has fewer restrictions than most languages, in this regard. Like, it's totally legal to use `property` or `id` or `list` as member names in your class, even though in theory those are all built-in commands or type names. Relatively few of Python's built-in names are restricted from being overridden if you really _want_ to. The only ones that are totally off limits are the 35 [keywords](https://docs.python.org/3/reference/lexical_analysis.html#keywords).) – FeRD Jul 03 '23 at 08:39

1 Answers1

20

It looks like you are using the pydantic module. You can't use the name global because it's a reserved keyword so you need to use this trick to convert it.

class User(BaseModel):
    id: int
    global_: bool

    class Config:
        fields = {
            'global_': 'global'
        }

or

class User(BaseModel):
    id: int
    global_: bool = Field(..., alias='global')

To create a class you have to use a dictionary (because User(id=1, global=False) also throws an error:

user = User(**{'id': 1, 'global': False})

To get data in correct schema use by_alias:

user.dict(by_alias=True)
mx0
  • 6,445
  • 12
  • 49
  • 54
  • 1
    I wonder, why it's not possible (not working) to use `global_` as parameter name when creating a new class with reserved keywords... – machin Nov 03 '22 at 08:13
  • 1
    @machin It is possible by adding `allow_population_by_field_name = True` to `Config` class – GooDeeJAY Nov 08 '22 at 14:57