6

Apologies if it is a silly question.

I am trying telethon for the first time and it fails to synchronize with my telegram API.

I get an IP address when I type this code: enter image description here

But I get this message when I try to connect to start or connect the client:

enter image description here

And finally, I get OperationalError: database is locked error when I try to log in using my phone.

enter image description here

The error message in full:

-------------------------------------------------------------------- 

OperationalError Traceback (most recent 
 call last)
<ipython-input-13-880bc0e4ea12> in <module>()
  1 from telethon import TelegramClient, sync
 ----> 2 client = TelegramClient('session_name', api_id, api_hash)
  3 
  4 client.connect()
  5 if not client.is_user_authorized():

 /anaconda3/lib/python3.7/site- 
 packages/telethon/client/telegrambaseclient.py in __init__(self, 
 session, api_id, api_hash, connection, use_ipv6, proxy, timeout, 
 request_retries, connection_retries, retry_delay, auto_reconnect, 
 sequential_updates, flood_sleep_threshold, device_model, 
 system_version, app_version, lang_code, system_lang_code, loop, 
 base_logger)
 221                 DEFAULT_DC_ID,
 222                 DEFAULT_IPV6_IP if self._use_ipv6 else 
 DEFAULT_IPV4_IP,
 --> 223                 DEFAULT_PORT
 224             )
 225 

 /anaconda3/lib/python3.7/site-packages/telethon/sessions/sqlite.py 
 in set_dc(self, dc_id, server_address, port)
184     def set_dc(self, dc_id, server_address, port):
185         super().set_dc(dc_id, server_address, port)
--> 186         self._update_session_table()
187 
188         # Fetch the auth_key corresponding to this data center

/anaconda3/lib/python3.7/site-packages/telethon/sessions/sqlite.py 
in _update_session_table(self)
205         # some more work before being able to save auth_key's 
 for

206         # multiple DCs. Probably done differently.
 --> 207         c.execute('delete from sessions')
208         c.execute('insert or replace into sessions values 
(?,?,?,?)', (
209             self._dc_id,

OperationalError: database is locked

What does coroutine object AuthMethods._start at mean? Why is it giving database is locked?

Ma'ruf
  • 167
  • 1
  • 10
J.Doe
  • 353
  • 1
  • 2
  • 12

6 Answers6

5

Referring to the Telethon documentation, The database will be locked if you don't close it properly.

In your case, you are using the same session file from many TelegramClient's at once.

First

In [9] client.start()

TelegramClient started

Second

In [13] client.connect()

TelegramClient's already active

This also causes the database is locked error. More info:

Ma'ruf
  • 167
  • 1
  • 10
  • okay it is not giving me `database is locked` anymore but it is still giving me this error `/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:1: RuntimeWarning: coroutine 'DialogMethods.get_dialogs' was never awaited """Entry point for launching an IPython kernel.` – J.Doe Jan 26 '19 at 16:40
  • 4
    How is this an acceptable answer when it doesn't give instructions how to end this error?! – Foad S. Farimani Apr 01 '20 at 17:12
  • 3
    Dear @Foad, He asked **Why is it giving database is locked?** And I explained why! – Ma'ruf Apr 05 '20 at 08:19
  • 1
    Also, remember to call `client.disconnect()` when you exit client. Otherwise, when reconnecting, you will receive `database is locked` message. – Kuznetsov-M Aug 21 '21 at 09:24
5

To solve the infamous

OperationalError: database is locked

error caused by sqllite3, one solution is to find the <SESSION_NAME>.session file created the first time you ran the code and delete it. Telethon puts those files in the same folder as your Python code or Jupyter Notebook. Or alternatively, you could use Python to get rid of the file automatically:

import os
import sys
os.chdir(sys.path[0])

if f"{SESSION_NAME}.session" in os.listdir():
    os.remove(f"{SESSION_NAME}.session")

assuming you are using the SESSION_NAME string variable to store the session name parameter of the TelegramClient() function.

E_net4
  • 27,810
  • 13
  • 101
  • 139
Foad S. Farimani
  • 12,396
  • 15
  • 78
  • 193
  • 4
    Please note that this should **not** be done in the finished product, or you will have to re-login every time, and hit flood waits that last days very soon. – Lonami Apr 02 '20 at 09:22
  • 2
    Dear @Lonami , You are right. but I haven't been able to find a better way to solve the `OperationalError: database is locked` problem. Do you have a better suggestion? – Foad S. Farimani Apr 02 '20 at 09:25
  • 1
    The accepted answer here is probably good. Just ensure you only ever create one client for one session. – Lonami Apr 02 '20 at 10:30
  • @Lonami the accepted solution did not solve the problem. Would you be kind to elaborate on it and maybe add some step by step expelnations to [the Documentation](https://docs.telethon.dev/en/latest/)? – Foad S. Farimani Apr 02 '20 at 10:32
  • 1
    Sorry, but I have not used Jupyter or IPython with Telethon before enough to be able to address that. – Lonami Apr 02 '20 at 10:38
  • 1
    @Lonami well, this is not a Jupyter/IPython problem AFIK. please try to run the code twice and see the problem. it is a sqlite3 issue and there are tens, if not hundreds of forum posts about it with no proper solution. – Foad S. Farimani Apr 02 '20 at 10:41
  • 2
    If you run the code twice and forget to call `disconnect` then **yes** it's likely that it errors. But if you disconnect cleanly this error should not occur, making sure no two instances run at the same time. – Lonami Apr 02 '20 at 11:06
  • @Lonami so we could have some form of try/except/catch and then put the `client.disconnect()` somewhere safe? – Foad S. Farimani Apr 02 '20 at 11:11
2

You have 2 problems here, first problem is related to authentication i guess, i will talk about database lock problem :

Session name that you have passed is already in use or active hence locked.

It becomes session file name if you use string as a parameter like here you have passed "name", this is one way to create a session.

other wise you can use telethon.sessions.abstract.Session object and pass it as parameter , this is second way.

And third way, you can simply pass None.

If it’s None, the session will not be saved, and you should call log_out() when you’re done.

client =  TelegramClient(None, api_id, api_hash)

Hope this helps.

Shirish Singh
  • 797
  • 7
  • 17
2

you can check the active processes for the session and if there are any, then close them before starting the client

pid = check_output(['fuser', 'anon.session'])
 if pid:
    check_output(['kill', pid])
  • 1
    While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value. You can find more information on how to write good answers in the help center: https://stackoverflow.com/help/how-to-answer . Good luck – nima Oct 25 '21 at 12:11
  • Also `fuser` is not always available, e.g. if you use the official Python docker image based on Debian, or if you are on Windows. In other words, this is an OS-specific fix. – Jonáš Jančařík Mar 21 '23 at 14:44
0

If you just need to get rid of this issue in Linux and run the program again, follow the below steps.

Step 1 - Find the session file. You can find a file called xxxxxxxxx.session In the same directory where you have your python script saved.

Step 2 - run fuser xxxxxxxxx.session (replace xxxxxxxxx.session with the file name found in step 1 )

Step 3 - You will see a response with an integer (Ex - 590219)

Step 4 - Run kill -9 590219 (replace 590219 with the integer found in the step 3)

Now run your program again

-3

If you're client.start() in 'if __name__ == '__main__':', you cannot log in to the telegram app and you will have

'OperationalError: database is locked'. You must delete 'if name == 'main'' before client.start()

bad_coder
  • 11,289
  • 20
  • 44
  • 72